C - 又一个strtok()和free()问题

时间:2014-03-10 20:39:34

标签: c free strtok

我试图了解如何在调用strtok()后完全释放内存。我在这里阅读了大部分已回答的问题,似乎没有一个问题能解决我的困惑。如果这是一个副本,请随时指出我回答我的问题的方向

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

在此处释放allocatedstring只会将字符串释放到替换strtok分隔符的第一个\0字符。所以它只会在“你好”之前清除。我检查了使用eclipse调试器并监视内存地址。

如何清除其余部分?我尝试了两件事,有一个额外的指针指向allocatestring的开头并释放(没有工作)并在调用strtok()后释放令牌(也没有工作)

那么如何清理现在allocatedstring之间\0的部分?

编辑:为了澄清,看到eclipse调试器中的内存地址块,我在最初通过调用{{1}分配的内存块中看到了字符串“HELLO WORLD FINE YOU” }}。在调用malloc之后,包含“HELLO”和第一个free()的块变为乱码,但其余的块保留了字符“FINE YOU”。我认为这意味着他们没有被释放。

2 个答案:

答案 0 :(得分:6)

free不了解\0已终止的字符串。

free将释放分配给malloc的内容,并且应该在这种情况下正常工作。

如果您free无效的证据仅仅是字符串数据仍然存在,那么您会误解free
将内存清零。它只是标记为可以使用 原始数据保留在该内存中。但是内存可能由malloc的下一个调用者分配,并且调用者可以随意覆盖您的数据,因为您不再拥有该数据了!

如果您希望清除内存(例如,如果它包含密码或安全密钥),必须在使用memset之前将其清除,然后再免费拨打电话。

同样,free仅将内存标记为“未分配,可供malloc使用”,并且不会清除内容。

PS 某些调试系统(如Visual Studio)将覆盖释放的数据,但仅在调试器中显示它已被释放。在C中合同不需要这种行为,只能帮助调试。通常情况下,释放的内存可能会填充 0xdeadbeef 等内容。

答案 1 :(得分:3)

这一行有一个小问题:

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

sizeof(allocatedstring)等于sizeof (char *);你为21个指向char 分配了足够的空间,而不是21个字符。这不是问题,因为char * 至少char一样大,但表示您正在处理的类型有些混乱。

也就是说,您不必担心allocatedstring *allocatedstring的大小;由于您正在分配足够的空间来容纳文字,因此您可以执行以下操作:

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

至于你所看到的行为......

free 释放与allocatedstring相关联的所有内存;您检查时部分内存尚未被覆盖的事实并不令人惊讶,因为free不会影响该内存的内容;它将包含最后写入的内容,直到其他内容分配并使用它。