使用Malloc功能的麻烦

时间:2018-01-06 20:20:31

标签: c malloc

我觉得我在理解C语言中的malloc函数时遇到了麻烦,尽管阅读了许多教程,尽管它似乎理论上有道理,但当我尝试做一些实际的事情时,我会被摧毁。

目前我以这种方式理解malloc:它是一个保留记忆的功能。 所以我尝试了这个:

   char *str;

   /* Initial memory allocation */
   str = malloc(3);
   strcpy(str, "somestring");
   printf("String = %s\n", str);

   /* Reallocating memory */
   str = realloc(str, 15);
   strcat(str, ".com");
   printf("String = %s", str);

   free(str);

   return(0);

输出结果为:

String = somestring
String = som(2-3 strange characters).com

我知道我不应该是malloc 3,而是字符串大小+1(null终结符)。然而奇怪的是,我从来没有在第一行中出现任何错误,在这种情况下"somestring"总是正确显示。只是第二部分,错误。当我删除realloc部分时,一切正常,即使理论上它不应该。我是否理解错误或有人可以解释这种行为吗?

3 个答案:

答案 0 :(得分:2)

超过数组的范围,例如由先前的malloc定义的那些边界是未定义的行为。在这样的操作之后,所有的赌注都关闭了。该程序甚至可能按预期运行,但它也可能产生一些非显而易见的事情。例如,在online C standard draft

中提供UB的定义
  

<强> 3.4.3

     

(1)使用不可移植或错误时的未定义行为行为   程序构造或错误数据,本国际   标准没有要求

     

(2)注意可能的未定义行为包括忽略这种情况   完全具有不可预测的结果,在翻译过程中表现出色   或者以文件化的方式执行程序   环境(有或没有发出诊断信息),到   终止翻译或执行(发布a   诊断信息)。

     

...

所以保留足够的内存,这种行为应该变成预期的行为。

答案 1 :(得分:1)

您对 malloc 的简要描述并不正确。它确实保留了内存。更准确地说,来自链接:

  

&#34;分配一个大小字节的内存块,返回指向   块的开头。&#34;

(强调我的)

但这并不是在准备创建C string时使用它的唯一考虑因素 除了理解malloc()之外, Undefined Behavior (1) 还有待了解,以及充其量会导致错误行为,但可能 much worse

通过为3个字节创建内存,并编写一个包含两个以上字符的字符串(以及一个NULL终止符),您已调用 undefined behavior (2) 。有时似乎会起作用,但有些人却不会。在这种情况下,您已经写入了您不拥有的内存。如果该内存不同时由另一个变量拥有。您可能会觉得一切正常,正如您在帖子中显示的结果所证明的那样。但如果它由另一个变量拥有,并被使用,则写入该位置的操作将失败。第二种情况是两者中较好的一种。第一个特别糟糕,因为它会使程序看起来很好,可能持续数小时,但是第一次发生冲突时,它会失败。

请记住,C中字符串的定义是一个以空字符结尾的字符数组:

char string[20];
char string2[3];
strcpy(string, "string content");//will always work
strcpy(string2, "string content");//may or may not appear to work

string将在内存中显示为:

|s|t|r|i|n|g| |c|o|n|t|e|n|t|\0|?|?|?|?|?|

?可以是任何值。

无法保证string2将包含哪些内容。

关于你的陈述:然而奇怪的是,我从来没有在第一行得到任何错误... ,因为 undefined behavior(3) 根据定义是不可预测的,以下可能会或可能不会帮助您查看效果,但由于过度夸大的值和分配,它可能会在某些时候导致访问冲突......

char shortStr[2][3] = {{"in"},{"at"}};//elements [0] & [1] will be provided memory locations close in proximity.
char longStr[100]={"this is a very long array of characters, this is a continuation of the same thing."}; 
strcpy(shortStr[0], longStr);

这可能会导致错误,因为shortStr[1]虽然不能保证,但是在内存位置会阻止副本在没有内存访问冲突的情况下发生。

答案 2 :(得分:0)

函数malloc可能会保留更多字节而不是您要求的字段,例如16,当您要求3时,出于与内存管理相关的原因。你不拥有其他13个字节,但其他人也没有,所以你可能会侥幸逃脱&#34;使用该内存没有任何冲突。在你演示产品之前:肯定会失败。