简体   繁体   中英

Why I cannot free a malloc'd string?

I have this code:

#define ABC "abc"

void main()
{
char *s = malloc(sizeof(char)*3);
printf("%p ", s);
s = ABC;
printf("%p ", s);
free(s);
}

This is the output:

0x8927008 0x8048574 Segmentation fault (core dumped)

As you can see, the address of string s changes after assignment (I think this is why free() gives segfault). Can anyone explain me why and how this happens? Thank you!

The line

s = ABC;

changes s to point to a different string which may well be in read-only memory. Attempting to free such memory results in undefined behaviour. A crash is likely.

I think you wanted

strcpy(s, ABC);

instead. This would copy the char array "abc" into s . Note that this will cause a further bug - s is too short and doesn't have space for the nul terminator at the end of ABC . Change you allocation to 4 bytes to fix this

char *s = malloc(4);

or use

char *s = malloc(sizeof(ABC));

if ABC is the max length you want to store.

void main() UB : main returns int

printf("%p", s) UB : calling a function accepting a variable number of arguments without a prototype in scope; UB : using a value of type char* where a value of type void* is expected.

free(s) UB : s is not the result of a malloc()

UB is Undefined Behaviour .

After

char *s = malloc(sizeof(char)*3);

s points to the memory allocated by malloc.

The line

s = ABC;

will change to

s = "abc";

after the prepossessing. Now this step makes s point to the string literal "abc" in the read-only area. Note that this also leaks the malloced memory.

Now since s is pointing to a non-malloced read-only memory, free it is a undefined behavior.

If you wanted to copy the string "abc" into memory pointed to by s you need to use strcpy as:

strcpy(s, ABC);

but note that to accommodate "abc" , s must be at least 4 characters long, to accommodate the NUL character as well.

Change the line: char *s = malloc(sizeof(char)*3);

to

char *s = (char *)malloc(sizeof(char)*3);

This clears up warnings many compilers warn about.

More than that I recommend that you make your code more flexible depending on what you do. If for some reason you change ABC to "ABCD", you will not have allocated enough space for all the characters.

Also, the string "ABC" has actually 4 characters (since there is a null at the end that terminates the strings). You'll see issues without that extra terminator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM