我正在努力掌握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) %d\n", i, A[i]);
}
}
例如,使用上面的示例代码,该代码运行无错误。即使我只分配了A
来保存10 * int,所以我希望循环只运行10次,然后再遇到错误。如果我将循环增加到大约30-40k,则会遇到分段错误。但是,如果我将大小增加到循环数量,它将总是按预期工作。因此,我知道如何避免该错误。.有点,我只是希望有人可能会足够友好地解释这是为什么。
编辑:事实证明,我不欣赏C不能检测到界限,Java和C ++对我的照顾太多了。我有未定义的行为,现在知道防止这些行为是我的工作。感谢所有回答。
答案 0 :(得分:9)
C不需要对数组访问执行任何边界检查。它可以让您读/写超过此内容而没有任何警告或错误。
您正在通过读写分配的内存末尾来调用undefined behavior。这意味着无法预测程序的行为。它可能会崩溃,它可能会输出奇怪的结果,或者(按照您的情况)可能会正常工作。
仅仅因为程序会崩溃并不意味着会崩溃。
答案 1 :(得分:4)
代码运行没有错误,但是仍然是错误的。您只是没有注意到它。您的循环用完了分配的区域,但是系统仍然没有意识到这一事实,直到您用尽了程序可以访问的更大的区域。
以这种方式生动描述:
<UNAVAILABLE><other data>1234567890<other data><UNAVAILABLE>
您的10个int
位于其他数据的中间,您可以读取甚至写入这些数据-造成非常不愉快的效果。 C不在这里握住您的手-仅当您耗尽全部可用内存时,程序才会崩溃,而不是之前。
答案 2 :(得分:1)
未定义的行为并不意味着“保证的分段错误”;在某些情况下可能会起作用。
没有办法知道在最终崩溃之前可以走多远。甚至取消引用边界之外的元素也是未定义的行为。
此外:如果malloc
成功,它将分配至少您需要的空间,甚至更多。