Freeing malloc will not erase char data

蹲街弑〆低调 提交于 2019-12-31 07:38:28

问题


I made a smaller scenario of my bigger problem. What I try to do is pass a string to a function which will make a new string out of it. However I ran into some problems.

I have defined string as

typedef char string[1024];

Then I have a function that takes a string and makes a new string which get filled with the old string and a dot char

string* add_sth_to_string(char* msg){
    string* newStr=malloc(sizeof(string)); // malloc a newStr
    strcpy(*newStr, msg);            // copying msg to newStr

    char buff[1024];                 // making a buffer
    strcat(buff, ".");               // adding a dot to buffer
    strcat(buff, *newStr);           // adding msg   to buffer
    strcpy(*newStr, buff);           // copying buffer to newStr
    return newStr;
}

Then in main I try to use this function 3 times for a new string each time:

for (i=0; i<3; i++){
    string* newStr;
    newStr=add_sth_to_string("test");
    printf("str: %s\n", *newStr);
    free(newStr);
    // can even printf here
}

This is the weird output I get:

str: .test
str: .test.test
str: .test.test.test

When I would expect to get:

str: .test
str: .test
str: .test

Anyone who can point out what is happening? Something else I find weird is that I can printf the value of newStr just after I have freed it.


回答1:


You are using buff without initializing it. Try:

char buff[1024];
buff[0] = 0;

Something else I find weird is that I can printf the value of newStr just after I have freed it.

Accessing memory after freeing it is undefined behavior. Typically, for performance reasons, free doesn't zero the memory.

That's 2 cases of undefined behavior in the same question + one really weird typedef. Keep it up!




回答2:


Try changing

strcat(buff, "."); 

into

strcpy(buff, "."); 

Or alternativly initialise buff when declaring it like so:

 char buff[1024] = "";



回答3:


You should clear content of buf[1024] each iteration.


UPDATE

Because buf[1024] will not be zero-ed automatically when allocated on the stack. And you choose strcat to concatenate two string, which will find a \0-terminate. Thus if buf contains some default value, it will introduce obfuscated output.

Use buf[1024] = ""; to allocate a buffer will correct the output.




回答4:


string* newStr=malloc(sizeof(string)); // malloc a newStr
strcpy(*newStr, msg);            // copying msg to newStr

This will also crash. string is a pointer so sizeof of it will return 4 or 8, not what you wanted to do.

Ok, forget about my remark you made a typedef, but I let it here to show you why the typedef is a bad idea. At first glance it obfuscated the fact that it was an array and not a pointer, on a 30 line program it's not a probleme, but when you have to maintain a 200 000 lines project (as I do), you will start to hate these kind of things.

Another point, you should avoid to work with fixed sized strings of 1024 bytes. 1024 is not that big (even homecomputer of the 80s had screens bigger than that) and for the majority if strings, which are fairly short, you spoil a lot of memory for nothing.



来源:https://stackoverflow.com/questions/8026917/freeing-malloc-will-not-erase-char-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!