Connal Sumlin
Connal Sumlin

Reputation: 41

Freeing an invalid pointer?

void resolve_paths(char* inputdir)
{
    char** tokens = malloc(64*sizeof(char*));
    char* ptr;
    char* slash = "/";
    int i = 0;

    ptr = strtok(inputdir,slash);
    while(ptr != NULL){
        if(strcmp(ptr,"~") == 0){
            ptr = getenv("HOME");
        }
        tokens[i] = (char*)calloc(64,sizeof(char));
        tokens[i] = ptr;
        printf("token[%i] = %s\n",i,tokens[i]);

        i++;
        ptr = strtok(NULL,slash);
    }
    int j;
    printf("freeing each element of tokens\n");
    for(j = 0; j < i; j++){
        printf("freeing token[%i]\n",j);
        free(tokens[j]);
    }
    free(tokens);
    puts("leaving resolve_paths\n");
    return;
}

My Output:

before call
token[0] = a
token[1] = b
token[2] = c
freeing each element of tokens
freeing token[0]
freeing token[1]
Error in `./a.out': free(): invalid pointer: 0x00007ff96dca12b2 ***

I guess I simply don't understand how malloc/calloc and free work. Why does this code run into a seg fault?

Upvotes: 1

Views: 1503

Answers (3)

Jack
Jack

Reputation: 133629

tokens[i] = (char*)calloc(64,sizeof(char));
tokens[i] = ptr;

This code doesn't do what you think it does. First you allocate 64 bytes and store the address in tokens[i], then you replace that address with ptr (thus losing the just allocated one which leaks away).

Probably you meant something like

tokens[i] = calloc(64,sizeof(char));
strncpy(tokens[i], ptr, 64);

which allocates the memory and then copy the string pointed by ptr into it. Mind that you don't need to cast the result of calloc or malloc in C since a void* is implicitly convertible to any other pointer.

In the end you try to free(tokens[i]) but the address contained is just a local address of inputdir adjusted by strtok, so it's not a dynamically allocated address which you can correctly free, that's why you get the error.

Upvotes: 0

Markus Dheus
Markus Dheus

Reputation: 576

Your are going wrong at tokens[i] = ptr;. You are assigning a pointer with that, not (as you probably expected) copying a string into the allocated memory, so you are freeing something you haven't actually allocated later on.

You have to use strcpy/strncpy for copying ptr into tokens[i]. Use something like strncpy(tokens[i],ptr,63) instead of tokens[i] = ptr;.

Upvotes: 2

TimLayne
TimLayne

Reputation: 124

As far as answering how malloc(),calloc() work, go here: How do malloc() and free() work? , excellent answers for your question.

Upvotes: 0

Related Questions