+ 1

Need help with understanding malloc & realloc

Hi there! I'm practicing dynamic memory allocation and copied a small program to play around with it. From my current understanding given the allocation of description = malloc(15 * sizeof (char)) the size of description should be 15bytes and it should show an error if I were to use strcat to add more text to the string in description. But when I print the size of description it is 8 in both cases before and after realloc 20*sizeof(char), despite using strcat and BOTH times the string is too large for the space allocated. Can someone help me with this? Here is the code and output: Output: Name: Adam Description: Adam is a DPS student. 8 Name: Adam Description: Adam is a DPS student. He is 24 years old. 8 https://code.sololearn.com/cHprnSgcPvIh/?ref=app

26th Jan 2023, 1:26 PM
Sarah Nour El Din
Sarah Nour El Din - avatar
8 Respostas
+ 4
strcat isn't safe, no prevention for buffer overflow. You could use strcpy_s (which is a safe version, you can specify the buffer size). You could make your error show by checking sizes before concatenating the string. Checking if the string length at the point plus the new string is less than the buffer size. This is in no way a good method, but this would work: #include <stdio.h> #include <stdlib.h> #include <string.h> int main () { char name[100]; char* description; int buff = 15; char strCat[] = "this is 15 long"; char strCat2[] = "this is over 15."; strcpy(name, "Adam"); description = (char*)malloc(buff * sizeof(char)); if (buff < (strlen(description) + strlen(strCat))) { fprintf(stderr, "Error - unable to allocate required memory"); } else { strcpy(description, strCat); } printf("Name:\t\t%s\n", name); printf("Description:\t%s\n", description); if (buff < (strlen(description) + strlen(strCat2))) { fprintf(stderr, "Error - unable to allocate required memory"); } else { strcpy(description, strCat2); } printf("Name:\t\t%s\n", name); printf("Description:\t%s\n", description); return 0; } Hopefully that makes sense :)
26th Jan 2023, 3:01 PM
DavX
DavX - avatar
+ 3
Sarah, malloc returns a void*, which you can cast to any type for example: ptr = (castType*) malloc(size); Also in your print statement, the sizeof() returns an unsigned long int - you can either cast this to an int or use the correct formatting %lu instead of %d. I've amennded your example to show both. I hope this helps :) #include <stdio.h> #include <stdlib.h> #include <string.h> int main () { char name[100]; char* description; strcpy(name, "Adam"); description = (char*)malloc(15 * sizeof(char)); if (description == NULL) { fprintf(stderr, "Error - unable to allocate required memory"); } else { strcpy(description, "Adam a DPS student. "); } printf("Name:\t\t%s\n", name); printf("Description:\t%s\n", description); printf("%d\n", (int)sizeof(description)); /* suppose you want to store a bigger description */ description = realloc(description, 20 * sizeof(char)); if(description == NULL) { fprintf(stderr, "Error - unable to allocate required memory."); } else { strcat(description, "He is 24 years old."); /*strcat = adds to string*/ } printf("Name:\t\t%s\n", name); printf("Description:\t%s\n", description); printf("%lu", sizeof(description)); return 0; }
26th Jan 2023, 1:57 PM
DavX
DavX - avatar
+ 3
Sarah, When you are using sizeof(description), you are getting 8 because that is the size of the pointer (usually 4 or 8 depending on 32/64...try checking description size before you use malloc and you will see it's the same). In C it's your own responsibility to keep track of the buffer size (usually with a separate var). There is also a warning present: warning: '__builtin_memcpy' writing 21 bytes into a region of size 15 overflows the destination I hope this helps :)
26th Jan 2023, 2:22 PM
DavX
DavX - avatar
+ 2
I am not going to be able to help with this much, but the best way to share code is through a link to a codebit, that way others can read better with syntax highlighting and test/tinker your code easier. Also, just leaving this video here incase it may be of use: https://youtu.be/xa4ugmMDhiE
26th Jan 2023, 1:49 PM
Justice
Justice - avatar
+ 2
Just adding up to DavX There's a variant of strcat() which allows us to specify how many characters to be copied over. This adds a sense of reaponsibility in using it for concatenating C-strings, and allows a bit of extra safety measures in regards to buffer overflow http://www.cplusplus.com/reference/cstring/strncat/
26th Jan 2023, 4:36 PM
Ipang
+ 1
Justice Thanks! I'll try to do that!
26th Jan 2023, 1:53 PM
Sarah Nour El Din
Sarah Nour El Din - avatar
+ 1
DavX Hi! Thanks so much for helping I appreciate it! One question remains for me which is why it doesn't print an error message when the string is longer than the size allocated for it? How is it 8 long when the string is longer than 8?
26th Jan 2023, 2:04 PM
Sarah Nour El Din
Sarah Nour El Din - avatar
0
DavX Ohhh I see! So in what case would I get the error message that the allocated space isn't enough? Or do I just get the warning and that's it? On the website I got the code from (tutorialspoint.com) they said "You can try the above example without reallocating extra memory, and strcat() will give an error due to lack of available memory in description." That's why I was wondering where that error message was in either case.
26th Jan 2023, 2:58 PM
Sarah Nour El Din
Sarah Nour El Din - avatar