问题描述
#include <stdio.h>
int main(void) {
int *x,*y;
x = malloc(sizeof(int));
for (int i = 0; i < 4; i++)
x[i] = i + 1;
y = x;
for (int i = 0; i < 4; i++)
printf("%d ",y[i]);
}
这正常工作并输出1 2 3 4
。
但是当i < 1000000
时会产生分段错误。
有人可以解释吗?
解决方法
您需要分配足够大的缓冲区。您只分配了sizeof(int),它通常为4个字节,并且足以容纳一个整数。不能存储1000000个元素。它纯粹出于偶然性而工作了4个元素,可能是因为尽管您覆盖了内存,但是您并没有破坏任何重要内容。这样的东西就是您应该使用的。
#include <stdio.h>
int main(void)
{
int count = 1000000;
int *x,*y;
x = malloc(sizeof(int) * count);
for (int i=0; i < count; i++)
x[i] = i+1;
y = x;
for (int i=0; i < count; i++)
printf("%d ",y[i]);
}
,
Undefined behaviour is undefined,您无法证明任何结果合理。
您已为一个整数分配了内存,当您尝试取消引用超出该范围的内存时(即i
== 1
),您正在调用UB。唯一有效的访问权限仅为x[0]
和x[0]
。
您只为一个int
分配了内存:
x = malloc(sizeof(int)); // malloc allocates a memory chunk to only hold one int object.
使用x
的{{1}}值以外的其他任何值为循环中的x[i] = i+1;
的{{1}}或y
的{{1}}编制索引printf("%d ",y[i]);
或0
)会调用undefined behavior,因为您将尝试写入未分配的内存并从中读取。
“ 这意味着如果我没有足够的缓冲区,它还会给
i
带来分段错误?”
完全正确。您知道这对未定义行为是一件坏事。它不需要提供错误的结果或错误。因此,x[0]
代码也被破坏了。
由于您仅在分配的内存之后写入了12个字节(因为y[0]
的公用字符为i < 4
),所以此方法可能会起作用,因为此后内存中没有其他必要的信息,但是您的代码还是绝对坏了。
您定义的内存少于使程序在该内存区域之后写入并更改程序堆栈的内存,这也是C和C ++中缓冲区溢出漏洞,增加缓冲区大小的情况>