malloc、memset 和免费的正确用法
Posted
技术标签:
【中文标题】malloc、memset 和免费的正确用法【英文标题】:malloc, memset and free correct usage 【发布时间】:2014-10-25 23:41:40 【问题描述】:我在使用 malloc、memset 和 free 时遇到问题,它无法按预期工作。问题在于最新的函数 printf,它不是打印“test”,而是打印一些奇怪的字符然后进行测试,例如“@#°test”。你能解释一下为什么吗?我注意到如果我在第二个 malloc 之后执行 memset,一切正常。另外,如果我不调用函数“function()”,即使没有 memset,我也真的不明白为什么一切正常
这是我的代码:
#define size 10
void function()
...
...other code...
...
char *b=malloc(size);
read(file_ds,b,size); //file_ds stands for file descriptor, correctly opened with open function.
memset(b,0,size);
free(b);
void main()
...
...other code...
...
function(); //If I don't call this, everything works fine, even without a memset
char *c=malloc(size);
strcat(c,"test");
printf("%s",c);
【问题讨论】:
malloc()
不会零初始化分配的内存,read()
NUL 也不会终止您的字符串。
【参考方案1】:
strcat
期望你给它的地址指向一个有效的字符串,它会通过寻找一个零字节来尝试找到该字符串的结尾。但是,您的指针指向未初始化的内存,尝试读取它是未定义的行为。
将malloc
更改为calloc
可为您提供初始化内存。然而,这可能是多余的,因为有一个初始化的初始段就足够了,你可以像这样实现L
char *c = malloc(size);
c[0] = '\0';
strcat(c, "test"); // OK
【讨论】:
所以,如果我想将一个字符串放入 malloc 并将其用于特定的字符串函数,我应该总是做类似你的例子的事情,或者在 malloc 之后立即执行 memset? @daimpa:嗯,您应该了解您使用的 API 期望什么,然后满足先决条件。我不想建议通过遵循食谱或烹饪书成为一名程序员。唯一真正的答案是您需要了解自己在做什么。通常这涉及阅读手册,因为没有人能记住 C API(这是非常不一致的)。当然,“always memset”将是一个糟糕的建议,尽管它会使您的代码正确。 @daimpa:strcpy (c, "test");
就不需要初始化内存了。
@kerrek SB 我正在从一本书中学习,但它似乎还不够好,但这是大学建议和遵循的,只有一小部分考试与 c 相关。 ..我在这里做问题是为了了解事情是如何工作的:)你能帮我理解为什么如果我在第一个函数中执行 printf("%s",b) 它会打印出与我之前看到的完全相同的奇怪字符“ test" 在 main 中,如果我不在 main 中调用 function(),为什么 strcat 可以正常工作?
@daimpa:仅此一次,试图解释您可能会看到的情况:当malloc
去操作系统获取新的、新鲜的内存时,该内存是全零的。所以如果你什么都不做,你可能会看到这样一个归零的内存区域。如果您已经使用并返回了一些内存,那么您将在以后的分配中得到不可预测的内容。以上是关于malloc、memset 和免费的正确用法的主要内容,如果未能解决你的问题,请参考以下文章