简体   繁体   中英

Segmentation fault on malloc

After running this function many (not sure exactly how many) times, it seg faults on a simple memory allocation. Why would this suddenly happen? I did notice something strange in GDB. In the function that calls it, normally there's 6-digit long hex value for wrd (wrd = 0x605140 for example), however on the call where it crashes, the hex value is only two digits long. (wrd=0x21). I also checked the wrd->length, and it's 3.

The line that it crashes on is...

char *word_temp = malloc(wrd->length * sizeof(char));

EDIT:

Here's the code that creates the wrd...

while(fgets(input, 100, src) != 0)
{
    int i = 0;
    while(input[i] != '\0')
    {
        i++;
    }

    struct word *wrd = malloc(sizeof(struct word));
    wrd->letters = input;
    wrd->length = i;

If I'm getting an overflow, how do I fix that?

Looks like wrd->length does not include the terminating '\\0' .

Fix 1, allocate word_temp like this:

char *word_temp = malloc( wrd->length + 1 );

Fix 2, include the '\\0' by modifying you length count loop:

int i = 0;
while(input[i++] != '\0') {}

This will increase i one more time than code in the question, which is easy to see if you consider case of input being empty.

Note that you need to do either fix 1 or fix 2, not both. Choose which ever works with rest of your code.


You probably have a second issue with this line:

wrd->letters = input;

It does not copy input, it copies the pointer. If you change contents of input , contents of wrd->letters changes too, because they point to same memory location. Also if input is a local char array, then once it goes out of scope, wrd->letters becomes a dangling pointer, which will be overwritten by other data, and modifying it after that will result in memory corruption.

Possible fix (depending on rest of your code) is to use strdup :

wrd->letters = strdup(input);

Remember that it is now allocated from heap, so when done, you must remember to do

free(wrd->letters);

About wrd being 0x21, that indicates either memory corruption, or that you actually have two separate wrd variables, and one one is left uninitialized.

For example, maybe wrd is a function parameter struct word *wrd , in which case you only modify the local value in function, it does not get passed back to the caller. To modify the pointer of caller, you need to have pointer to pointer: struct word **wrd and then do (*wrd) = malloc... and (*wrd)->letters... etc.

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