I have just discovered your channel and your videos are super helpful, super easy to follow and super amazing. please keep making videos about computer programming and C language. ✨✨✨
Thank you very much Mohammad! :-) I’m very glad to hear you enjoy the videos. If you have any video ideas now or in the future please feel free to make requests. I can’t make videos for all requests, but I like to make videos in response to viewer requests when I can. :-)
@@PortfolioCourses thank you for your keeping getting feedback from viewers. Please, would you make videos about assembly language as I find it hard for me to understand it? I love your way of simplifying topics, I was struggling in C language until your videos made things so easy.
@@mohammadahmedragab837 I haven't done assembly language in awhile, but one day I'm hoping to do videos on assembly language too. :-) Thanks for the suggestion and feedback.
You discuss so well that I could understand it even watching only once. I was hesitant at first because I haven't used memcpy alongside with structs. What IDE are you using btw?
Thank you so much for this video. I have a question about casting. I've seen many examples where unsigned char* was used instead of char*. Why is it that a lot of people say that it's a lot better to use unsigned char*?
You're welcome Yasmine! :-) And that's a great question. To my knowledge, if we're doing comparisons or arithmetic operations with chars, the signed vs. unsigned issue can matter. Because we're trying to see for example if char X < char Y, and the "signedness" of the char values can effect whether X = Y. For the copying we're doing in this video, to the best of my knowledge it doesn't matter because we're just doing an assignment operation. This stackoverflow answer tries to explain things better than I think I am able to: stackoverflow.com/questions/62442859/char-vs-unsigned-char-what-is-the-difference. :-)
Really interesting example, but it could be confusing for a beginner because in your function you do operations on char_dest and you finally return dest I'm not sure everyone understand why it works like that :)
I hear you... this topic is not really for beginners so I'm assuming people likely know what concepts like typecasting and pointers are if they are looking for this topic, otherwise the video will be 30 minutes long if I start explaining those things too. 🙂 For any beginners watching this video that wants to learn more these topics, these may be some relevant videos to help you out: Introduction to Pointers: ruclips.net/video/2GDiXG5RfNE/видео.html Typecasting: ruclips.net/video/xKOPZ4mEH3I/видео.html
it's really awesome explanation and because of you i managed to make my own memcpy void *ft_memcpy(void *dst, const void *src, size_t n) { size_t i; char *char_dst; char *char_src; char_dst = (char *)dst; char_src = (char *)src; if (dst == NULL && src == NULL) return (NULL); i = 0; while (i < n) { char_dst[i] = char_src[i]; i++; } return (dst); }
I just subscribed, your videos are so helpful, great explanation straight to the point, I'm in college and we use C . anyway ur channel is great keep up sir
Hi sir in this video I have noticed something wired . My question is it correct to check void *dest with Null in the if condition without type casting to another one ...
Yes, null is a special value in C which essentially means 'pointer to nothing', and so we can use it with any type pointer and it will work correctly. :-)
I go over the difference in this video on memmove: ruclips.net/video/DGwdAQauEV4/видео.html. I also have a video on memcpy: ruclips.net/video/PThPm24wGEo/видео.html. But I think that's a good idea for a video, I might make a separate video on that topic specifically, so thank you for the idea. :-)
hi professor could you explain why we cast to char pointer, but it works on all types like integer arrays wich in this case point to integer not a char
A char essentially means "one byte". So when we cast to char, we are copying "one byte at a time". We do this because the function's third argument 'n' is "the number of bytes to copy", so we want to copy exactly that many bytes. Now technically, a char could be something other than a byte (8 bits). So technically, 'n' is "the number of char-sized units" to copy. As a practical matter, this is very rare, it would be something on niche systems/compilers, but it's technically possible.
I'm not sure about c but with c++ i think it's better to make to second argument a const in case we wanna pass a string literal : void *stdmemcpy(void *dest,const void*buffer ,size_t count){ unsigned char* casteddest = (unsigned char*)dest ; unsigned char* castedbuffer = (unsigned char*)buffer ; while(dest !=nullptr && buffer !=nullptr && count){ *casteddest = *castedbuffer ; ++casteddest , ++castedbuffer , --count ; } return dest ; } also i'm sorry i'm asking too much questions lately but i'm curious why u did not check if the second argument is a NULL and also i'm really confuse about the meaning of buffer in c/c++ or in programming in general i mean i know that the buffer is a memory area that stores data while it's being moved right ? but why we call an array that is allocated in the stack or in the heap a buffer ? thank u for great videos 😉
We can still pass a string literal this way. Making it const would help to ensure the function is not able to modify the source though. The behaviour of memcpy() is undefined for NULL pointers so we don't need to check them, but we could if wanted to as well. 🙂 The term 'buffer' gets used pretty permissively, basically we could use the term for "something that stores a chunk or black of data". It might be holding it for processing, for moving, etc.
Great question! :-) The compiler will not allow us to dereference a void pointer because it doesn't know the size of the thing it is pointing to. So we can't perform the copy with void pointers, without the ability to dereference the pointer (or use array notation with the pointers either). That's why we create local char type pointers and cast the void pointer to a char pointer, which then allows us to copy one byte at a time.
So it's really just an example to show that you can copy "any" block of memory. 🙂 But if the struct is on the heap (with a flexible array member), assignment with = won't work to create a copy of the struct, in which case memcpy will be helpful.
@@AlessioSangalli Not always, if the structs have flexible array members it will not work: ruclips.net/video/1h27lYe15iI/видео.html. I edited my comment to clarify.
Yes abdul, the "real" memcpy() function has undefined behaviour when we pass it a NULL pointer: "If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined." So for our implementation, we can expect it to crash, we could have done something else though too, and that would be valid as well as the behaviour is undefined "officially".
I did implement the memcpy() function, And i did try to run some test but my out put are not the same. I was trying to modify the strings which is my destination and the source. check out the code; #include "libft.h" void *ft_memcpy(void *dest, const char *src, size_t n) { unsigned int i = 0; unsigned char *dst = (unsigned char *)dest; unsigned char *s = (unsigned char *)src; while (s[i] != '\0' && i < n) { dst[i] = s[i]; i++; } return dest; } int main() { char dest[] = "Amone Patrick"; ft_memcpy(&dest[7], &dest[6], 5); printf("This is the output for modified: %s ", dest); memcpy(dest + 7, &dest[6], 5); printf("This is the output for Built-in: %s ", dest); } output: This is the output for modified: Amone PPPPPPk This is the output for built-in: Amone PPatrik
The condition s[i] != '\0' will stop the copy operation whenever a 0 is encountered, as \0 == 0, so that's unusual to have in a "memcpy" function. It also means that the null terminator at the end of a string will not be copied, if you're copying strings, which means the string will not be properly null terminated. I don't know why you are copying into a destination that is ahead of the source and overlaps with the source, that is unusual. You're also not calling the functions the same way, though I don't think that will matter, if you're trying to understand why the behaviour is different it would be a good idea to call them the exact same way. memcpy()'s behaviour is undefined when the source and destination overlap, so we can't really say much about what "should" happen in this scenario either, your function is "correct" and memcpy is "correct" because the source and destination overlap: vgable.com/blog/2008/05/24/memcopy-memmove-and-speed-over-safety/
Thank you Kevin for making character casting easy to understand and why we need it to use it.
You're welcome Firas! :-)
I have just discovered your channel and your videos are super helpful, super easy to follow and super amazing.
please keep making videos about computer programming and C language.
✨✨✨
Thank you very much Mohammad! :-) I’m very glad to hear you enjoy the videos. If you have any video ideas now or in the future please feel free to make requests. I can’t make videos for all requests, but I like to make videos in response to viewer requests when I can. :-)
@@PortfolioCourses thank you for your keeping getting feedback from viewers.
Please, would you make videos about assembly language as I find it hard for me to understand it?
I love your way of simplifying topics, I was struggling in C language until your videos made things so easy.
@@mohammadahmedragab837 I haven't done assembly language in awhile, but one day I'm hoping to do videos on assembly language too. :-) Thanks for the suggestion and feedback.
You discuss so well that I could understand it even watching only once. I was hesitant at first because I haven't used memcpy alongside with structs. What IDE are you using btw?
That's great I'm so glad to hear the explanation was helpful for you. :-) And in this video I'm using Xcode on a Mac.
Thank you so much for this video. I have a question about casting. I've seen many examples where unsigned char* was used instead of char*. Why is it that a lot of people say that it's a lot better to use unsigned char*?
You're welcome Yasmine! :-) And that's a great question. To my knowledge, if we're doing comparisons or arithmetic operations with chars, the signed vs. unsigned issue can matter. Because we're trying to see for example if char X < char Y, and the "signedness" of the char values can effect whether X = Y. For the copying we're doing in this video, to the best of my knowledge it doesn't matter because we're just doing an assignment operation. This stackoverflow answer tries to explain things better than I think I am able to: stackoverflow.com/questions/62442859/char-vs-unsigned-char-what-is-the-difference. :-)
Really interesting example, but it could be confusing for a beginner because in your function you do operations on char_dest and you finally return dest
I'm not sure everyone understand why it works like that :)
I hear you... this topic is not really for beginners so I'm assuming people likely know what concepts like typecasting and pointers are if they are looking for this topic, otherwise the video will be 30 minutes long if I start explaining those things too. 🙂 For any beginners watching this video that wants to learn more these topics, these may be some relevant videos to help you out:
Introduction to Pointers: ruclips.net/video/2GDiXG5RfNE/видео.html
Typecasting: ruclips.net/video/xKOPZ4mEH3I/видео.html
Congrats on 2k!!
Sir,can u please do a video about boolean functions use - cases in C.
I see in ur videos that u use a lot of boolean functions
I’ll add it to the todo list! Did you any particular use cases in mind? :-)
it's really awesome explanation and because of you i managed to make my own memcpy
void *ft_memcpy(void *dst, const void *src, size_t n)
{
size_t i;
char *char_dst;
char *char_src;
char_dst = (char *)dst;
char_src = (char *)src;
if (dst == NULL && src == NULL)
return (NULL);
i = 0;
while (i < n)
{
char_dst[i] = char_src[i];
i++;
}
return (dst);
}
Awesome, nice work! :-)
I just subscribed, your videos are so helpful, great explanation straight to the point, I'm in college and we use C . anyway ur channel is great keep up sir
Thank you very much Mohamed! :-)
Hi sir in this video I have noticed something wired .
My question is it correct to check void *dest with Null in the if condition without type casting to another one ...
Yes, null is a special value in C which essentially means 'pointer to nothing', and so we can use it with any type pointer and it will work correctly. :-)
Why do you hvae to cast the dest and src? Isn't it enough just to assign the pointer to the first element to the new char pointer?
also would there be a difference if we used an unsigned char instead?
shouldn't you check if dest is also not null ?
After copying, is it safe to free the source pointer?
thank you man, can you make another vedio about the defrence between memmove and memcpy
I go over the difference in this video on memmove: ruclips.net/video/DGwdAQauEV4/видео.html. I also have a video on memcpy: ruclips.net/video/PThPm24wGEo/видео.html. But I think that's a good idea for a video, I might make a separate video on that topic specifically, so thank you for the idea. :-)
hi professor could you explain why we cast to char pointer, but it works on all types like integer arrays wich in this case point to integer not a char
A char essentially means "one byte". So when we cast to char, we are copying "one byte at a time". We do this because the function's third argument 'n' is "the number of bytes to copy", so we want to copy exactly that many bytes.
Now technically, a char could be something other than a byte (8 bits). So technically, 'n' is "the number of char-sized units" to copy. As a practical matter, this is very rare, it would be something on niche systems/compilers, but it's technically possible.
@@PortfolioCourses very helpfull thank you so much
You're welcome! :-)
I'm not sure about c but with c++ i think it's better to make to second argument a const in case we wanna pass a string literal :
void *stdmemcpy(void *dest,const void*buffer ,size_t count){
unsigned char* casteddest = (unsigned char*)dest ;
unsigned char* castedbuffer = (unsigned char*)buffer ;
while(dest !=nullptr && buffer !=nullptr && count){
*casteddest = *castedbuffer ;
++casteddest , ++castedbuffer , --count ;
}
return dest ;
}
also i'm sorry i'm asking too much questions lately but i'm curious why u did not check if the second argument is a NULL and also i'm really confuse about the meaning of buffer in c/c++
or in programming in general i mean i know that the buffer is a memory area that stores data while it's being moved right ? but why we call an array that is allocated in the stack or in the heap a buffer ?
thank u for great videos 😉
We can still pass a string literal this way. Making it const would help to ensure the function is not able to modify the source though. The behaviour of memcpy() is undefined for NULL pointers so we don't need to check them, but we could if wanted to as well. 🙂 The term 'buffer' gets used pretty permissively, basically we could use the term for "something that stores a chunk or black of data". It might be holding it for processing, for moving, etc.
@@PortfolioCourses much clear now thank u 👍keep it up 💥
@@justcurious1940 Great!
why we couldn't casting src and dst pointer from void* to char* and had to create a 2 local pointers : char_dest and char_src ?
Great question! :-) The compiler will not allow us to dereference a void pointer because it doesn't know the size of the thing it is pointing to. So we can't perform the copy with void pointers, without the ability to dereference the pointer (or use array notation with the pointers either). That's why we create local char type pointers and cast the void pointer to a char pointer, which then allows us to copy one byte at a time.
Why use memcopy with structs when one can do student2 = student1; ???
So it's really just an example to show that you can copy "any" block of memory. 🙂 But if the struct is on the heap (with a flexible array member), assignment with = won't work to create a copy of the struct, in which case memcpy will be helpful.
@@PortfolioCourses if you have structs allocated on the heap and use pointers to them, you can do *s1 = *s2 and it will work, it does not matter...
@@AlessioSangalli Not always, if the structs have flexible array members it will not work: ruclips.net/video/1h27lYe15iI/видео.html. I edited my comment to clarify.
mem_cpy crashes when src is NULL
Yes abdul, the "real" memcpy() function has undefined behaviour when we pass it a NULL pointer:
"If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined."
So for our implementation, we can expect it to crash, we could have done something else though too, and that would be valid as well as the behaviour is undefined "officially".
I did implement the memcpy() function, And i did try to run some test but my out put are not the same. I was trying to modify the strings which is my destination and the source.
check out the code;
#include "libft.h"
void *ft_memcpy(void *dest, const char *src, size_t n)
{
unsigned int i = 0;
unsigned char *dst = (unsigned char *)dest;
unsigned char *s = (unsigned char *)src;
while (s[i] != '\0' && i < n)
{
dst[i] = s[i];
i++;
}
return dest;
}
int main()
{
char dest[] = "Amone Patrick";
ft_memcpy(&dest[7], &dest[6], 5);
printf("This is the output for modified: %s
", dest);
memcpy(dest + 7, &dest[6], 5);
printf("This is the output for Built-in: %s
", dest);
}
output: This is the output for modified: Amone PPPPPPk
This is the output for built-in: Amone PPatrik
The condition s[i] != '\0' will stop the copy operation whenever a 0 is encountered, as \0 == 0, so that's unusual to have in a "memcpy" function. It also means that the null terminator at the end of a string will not be copied, if you're copying strings, which means the string will not be properly null terminated. I don't know why you are copying into a destination that is ahead of the source and overlaps with the source, that is unusual. You're also not calling the functions the same way, though I don't think that will matter, if you're trying to understand why the behaviour is different it would be a good idea to call them the exact same way. memcpy()'s behaviour is undefined when the source and destination overlap, so we can't really say much about what "should" happen in this scenario either, your function is "correct" and memcpy is "correct" because the source and destination overlap: vgable.com/blog/2008/05/24/memcopy-memmove-and-speed-over-safety/