我觉得我在理解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部分时,一切正常,即使理论上它不应该。我是否理解错误或有人可以解释这种行为吗?
答案 0 :(得分:2)
超过数组的范围,例如由先前的malloc
定义的那些边界是未定义的行为。在这样的操作之后,所有的赌注都关闭了。该程序甚至可能按预期运行,但它也可能产生一些非显而易见的事情。例如,在online C standard draft:
<强> 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;使用该内存没有任何冲突。在你演示产品之前:肯定会失败。