释放无效指针?

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;
}

我的输出:

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 ***

我想我根本不明白 malloc/calloc 和免费工作。为什么此代码 运行 会出现段错误?

至于回答 malloc()calloc() 的工作原理,请转到此处:How do malloc() and free() work?, 您问题的最佳答案。

你在 tokens[i] = ptr; 处出错了。您正在为它分配一个指针,而不是(正如您可能预期的那样)将字符串复制到分配的内存中,因此您释放了一些您稍后实际上没有分配的东西。

你必须使用 strcpy/strncpy 将 ptr 复制到 tokens[i]。使用 strncpy(tokens[i],ptr,63) 而不是 tokens[i] = ptr;.

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

此代码与您认为的不同。首先分配 64 个字节并将地址存储在 tokens[i] 中,然后用 ptr 替换该地址(从而丢失刚刚分配的泄漏)。

可能你的意思是

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

分配内存,然后将ptr指向的字符串复制进去。请注意,您不需要在 C 中转换 calloc 或 malloc 的结果,因为 void* 可以隐式转换为任何其他指针。

最后你尝试free(tokens[i]),但包含的地址只是inputdir的本地地址,由strtok调整,所以它不是动态分配的地址,你可以正确free,这就是你得到错误的原因。