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 和免费的正确用法的主要内容,如果未能解决你的问题,请参考以下文章

memset和wmemset用法记录

C语言中free函数的用法

关于memalign和malloc的区别

malloc和calloc用法

浅谈new/delete和malloc/free的用法与区别

memset函数用法