我试图了解如何在调用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”。我认为这意味着他们没有被释放。
答案 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
不会影响该内存的内容;它将包含最后写入的内容,直到其他内容分配并使用它。