سؤال

I am trying to understand how to free up memory fully after calls to strtok(). I read most of the answered questions here and none seemed to address the point of my confusion. If this is a duplicate feel free to point me to the direction of something that answers my question

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char * aliteral = "Hello/world/fine/you";

    char * allocatedstring;

    char * token;
    int i=0;


    allocatedstring=(char *) malloc(sizeof(allocatedstring)*21);
    allocatedstring=strcpy(allocatedstring,aliteral);

    token = strtok(allocatedstring, "/");
    token = strtok(NULL, "/");
    token = strtok(NULL, "/");
    token = strtok(NULL, "/");



    printf("%s\n",allocatedstring);
    printf("%s\n",token);

    free(allocatedstring);


    return 0;
}

Freeing allocatedstring here only frees up the string up to the first \0 character that replaced strtok's delimiter. So it only clears up until "Hello". I checked that using eclipse debugger and monitoring the memory addresses.

How do I clear the rest of it? I tried 2 things, having 1 extra pointer point to the start of allocatedstring and freeing that (didnt work) and freeing token after call to strtok() (didnt work either)

So how do I clean up the parts of allocatedstring that are now between \0 's ?

EDIT : To clarify, seeing the memory address blocks in eclipse debugger, I was seeing the string "HELLO WORLD FINE YOU" in the memory blocks that were initially allocated by the call to malloc. After the call to free(), the blocks containing "HELLO" and the first \0 turned to gibberish, but the rest of the blocks kept the characters "FINE YOU". I assumed that meant that they were not freed.

هل كانت مفيدة؟

المحلول

free has no knowledge of \0 terminated strings.

free will free what was allocated with malloc, and should work properly in this situation.

If your evidence that free is not working is simply that the string data still exists, then you misunderstand free.
It does not zero out the memory. It simply marks it as available for use.
The original data remains in that memory. But the memory may be allocated by the next caller of malloc, and that caller will be able to overwrite your data at will, because you don't own that data anymore!

If you want that memory cleared (such as, if it contains a password or a security key), you must clear it out with something like memset, before you call free.

Again, free only marks the memory as "unallocated, available for use by malloc", and does not clear out the contents.

PS Some debugging systems, such as Visual Studio, will overwrite freed data, but only to make it obvious in the debugger that it has been freed. That behavior is not contractually needed in C, and only aids in debugging. Typically, freed memory may be filled with something like 0xdeadbeef.

نصائح أخرى

You have a minor issue on this line:

allocatedstring=(char *) malloc(sizeof(allocatedstring)*21);

sizeof(allocatedstring) is equal to sizeof (char *); you're allocating enough space for 21 pointers to char, not 21 characters. This isn't a problem, since a char * is going to be at least as large as a char, but indicates some confusion about what types you're dealing with.

That said, you don't have to worry about the size of allocatedstring or *allocatedstring; since you're allocating enough space to hold the literal, you can do the following:

allocatedstring = malloc( strlen( aliteral ) + 1 ); // note no cast

As for the behavior you're seeing...

free is releasing all the memory associated with allocatedstring; the fact that part of the memory hadn't yet been overwritten when you checked isn't surprising, because free doesn't affect the contents of that memory; it will contain whatever was last written to it until something else allocates and uses it.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top