我正在尝试掌握malloc
,到目前为止,我在测试和使用它时大多得到意想不到的结果。
int main(int argc, char** argv)
{
int size = 10;
int *A;
A = (int *)malloc(size * sizeof(int));
for (int i = 0; i < 10000; i++)
{
A[i] = i;
}
for (int i = 0; i < 10000; i++)
{
printf("%d) %dn", i, A[i]);
}
}
以上面的此示例代码为例,代码运行时没有错误。即使我只分配了A
来保持 10 * int,所以我希望循环在遇到错误之前只运行 10 次。如果我将循环增加到大约 30-40k,则会遇到分段错误。但是,如果我将大小增加到循环量,它将始终按预期工作。所以我知道如何避免错误..有点,我只是希望有人能好心地解释为什么会这样。
编辑:事实证明,我不欣赏C没有检测到越界,Java和C++对我的照顾太多了。我有未定义的行为,现在知道我的工作是防止它们。感谢所有回复的人。
对数组访问执行任何边界检查。 它可以让你读/写过去,没有任何警告或错误。
您通过读取和写入超过分配的内存末尾来调用未定义的行为。 这意味着无法预测程序的行为。 它可能会崩溃,可能会输出奇怪的结果,或者它可能(如您的情况)看起来工作正常。
仅仅因为程序可以崩溃并不意味着它会崩溃。
代码运行没有错误,但仍然是错误的。你只是没有注意到它。您的循环超出了分配的区域,但系统仍然不知道这一事实,直到您的程序可能访问的更大区域用完为止。
这样想:
<UNAVAILABLE><other data>1234567890<other data><UNAVAILABLE>
您的 10 int
s位于其他数据的中间,您可以读取甚至写入这些数据 - 产生非常令人不快的效果。C 在这里没有牵着你的手 - 只有当你用完总可用内存时,程序才会崩溃,而不是之前。
未定义的行为并不意味着"保证分段错误";在某些情况下它可能有效。
在最终崩溃之前,没有办法知道你可以超出数组边界多远;即使取消引用一个超出边界的元素也是未定义的行为。
另外:如果malloc
成功,它将至少分配您请求的空间,甚至可能更多。