在动态分配的数组中存储数据(字符串)超出范围

时间:2016-07-11 06:40:04

标签: c string

以下是一个非常简单的C程序:

char *p = (char*)calloc(5,sizeof(char));
strcpy(p,"Elephant");
printf("String = %s\n", p);
p[6] = 'D';
printf("String = %s\n", p);

使用calloc()分配5个元素的char数组,并使用strcpy()将字符串复制到数组中。以下是输出:

String = Elephant
String = ElephaDt

显然,我只要求5个char元素,因此很想知道为什么OS内存mgmt允许我在 p 中存储更多元素超出动态分配空间的范围。如果我只分配了5个字符的空格,strcpy()是如何存储一个更大的字符串“Elephant”,其长度大于5个字符?

3 个答案:

答案 0 :(得分:5)

分配内存时,通常由内存管理器完成。这些通常会从操作系统中分配更大的内存块,然后将其交给malloc()和较小部分的朋友。

因此,您分配的5个字节很可能是较大块内存的一部分。由于您违反了分配的边界,而不是较大的块,操作系统不会干扰。但是,这可能意味着您通过覆盖附近的分配来破坏您自己程序的其他内存。它甚至可能意味着您损坏了内存管理器用于跟踪已分配和可用内存的数据。但这不是一个给定的。这只是未定义的行为。

未定义的行为并不意味着您必须得到运行时错误。它也可以意味着没有任何事情发生,或者你开始WW3,或其他什么。它未定义,但并不一定意味着崩溃。

答案 1 :(得分:0)

使用strcpy()会将您想要的字符数复制到您定义的目的地。它不会检查数组的范围。它只是一直复制,直到它复制了整个单词。

这意味着您可以在没有编译错误的情况下执行此操作。但是,这会调用(请参阅this link以了解它),因为您无法确定在分配的内存范围之外会发生什么。在你的情况下,没有发生任何不好的事情(实际上发生了什么是你想要发生的事情),但你一般不能确定。

答案 2 :(得分:-1)

您正在动态分配的数组,它已从堆内存中分配。正如@Rudy Velthuis所提到的,堆内存以大块分配。因此,在正常情况下,您的程序运行正常。但请考虑一个场景,其中存在紧张的情况,并且您计算机的大部分内存都被占用。那时,堆中一个进程的内存块很可能位于堆块旁边,分配给您的进程。 并且使情况更具概率性,假设您的阵列在堆的最末端被分配,然后访问超出已分配内存的末尾,将使您的程序访问其他程序的堆。 在这种情况下,操作系统将介入,拒绝访问您的程序,您的程序将崩溃。

希望,它会帮助你。