Malloc函数的问题

Malloc函数的问题,c,malloc,C,Malloc,我想我在理解C中的malloc函数时遇到了困难,尽管我读了很多教程,尽管它似乎在理论上是有意义的,但当我试图做一些实际的事情时,我会被摧毁 目前我对malloc的理解是这样的:它是一个保留内存的函数。 所以我试了一下: char *str; /* Initial memory allocation */ str = malloc(3); strcpy(str, "somestring"); printf("String = %s\n", str); /*

我想我在理解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

我知道我不应该使用malloc3,而应该使用字符串大小+1(空终止符)。然而奇怪的是,我从来没有在第一行中得到任何错误,在这种情况下,
“somestring”
总是正确显示。只剩下第二部分了。当我删除realloc部分时,一切正常,即使理论上不应该如此。我是否理解有什么错误,或者有人能解释一下这种行为吗?

超过数组的界限,例如,以前的
malloc
定义的界限,是未定义的行为。在这样一次行动之后,所有的赌注都输光了。该程序甚至可能按预期运行,但也可能产生一些不明显的结果。例如,在以下内容中给出UB的定义:

3.4.3

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

(2) 注意:可能的未定义行为包括忽略情况 完全不可预测的结果,在翻译过程中的行为 或以文件化的方式执行程序 环境(无论是否发出诊断消息),以 终止翻译或执行(通过发布 诊断信息)

因此,请保留足够的内存,这种行为应该会变成预期的行为。

您对的简要描述没有错误。它确实保留了内存。更准确地说,从链接:

分配一个大小为字节的内存块,返回指向 这是街区的起点。”

(强调矿山)

但这并不是在准备创建
C字符串时使用它的唯一考虑因素
除了了解
malloc()
之外,还需要了解最多会导致错误行为的方式,但也有可能

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

还要记住,
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
字符串
将在内存中显示为:

|s|t|r|i|n|g| |c|o|n|t|e|n|t|\0|?|?|?|?|?|
其中
可以是任何值

无法保证
string2
将包含什么内容

关于您的声明:然而奇怪的是,我从来没有在第一行中得到任何错误…,因为根据定义是不可预测的,下面的内容可能会或可能不会帮助您看到效果,但由于过度夸大的值和赋值,它可能会在某个时候导致访问冲突

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]
虽然不保证,但位于一个内存位置,可以防止在没有内存访问冲突的情况下发生复制

由于与内存管理相关的原因,函数
malloc
可能会保留比您要求的更多的字节,例如,当您要求3时,会保留16个字节。您不拥有其他13个字节,但也没有其他人拥有,因此您可能会在不存在任何冲突的情况下“侥幸”使用该内存。在您演示产品之前:那么它肯定会失败。

是未定义的,但是……写入您没有合法访问权限的内存会使您的程序具有未定义的行为。错误是未定义行为的一种表现形式,但“工作正常,然后表现怪异”也是一种有效的表现形式。这就是为什么你不应该写你不应该写的内存。未定义的行为意味着未定义的结果。一开始就把它做好。在我看来,问“为什么我绊倒时没有摔倒”的问题是愚蠢的。答案是“因为你没有”。@WeatherVane是的,但如果我绊倒了,我会摔倒在地,不会像C中那样开始飞到空中。但是kk我想我现在理解了未定义的行为:)停止做你知道是错误的事情。