C语言向连续地址赋值失败且出现运行时错误的原因是什么?
问题原因
你这段代码的核心问题是触发了非法内存越界访问,属于C语言标准定义的未定义行为,运行报错、结果不符合预期都是这类问题的典型表现。
你提交的代码如下:
#include<stdio.h> int main() { int i; int *p; int a = 10; p= &a; printf("address of a = %x\n",p); *(p + 0) = 5; *(p + 1) = 6; *(p + 2) = 7; *(p + 3) = 8; for(i=0; i < 4; i++) { printf("address = %x value = %x\n",(p+i),*(p+i)); } return 0; }
具体错误原因如下:
- 你定义的
a是单个int类型变量,运行时栈上只会给它分配sizeof(int)大小的内存(通常为4字节),只有p指向的这4字节空间是你可以合法读写的区域。 - C语言的指针算术是按指针指向的类型长度步进的:
p + n等价于地址偏移n * sizeof(int),你操作*(p+1)、*(p+2)、*(p+3)时,已经在访问a后面不属于你申请的内存空间。 - 这些越界的内存区域可能存储了栈上其他变量的值、栈保护标记、函数返回地址等关键数据,写入操作会直接破坏栈的正常结构:轻则导致程序运行结果异常,重则直接触发段错误崩溃。
- 你观察到“值没有成功分配到连续地址”也是未定义行为的正常表现:越界写入的内容可能被后续的程序逻辑覆盖,或者对应的内存地址本身没有读写权限,结果完全不可预测。
修正方案
如果你需要连续读写4个int类型的数据,应该直接定义长度为4的int数组,操作系统会自动分配连续的合法内存:
#include<stdio.h> int main() { int i; int *p; int a[4]; // 定义长度为4的int数组,分配连续4*4=16字节合法内存 a[0] = 10; p = &a[0]; printf("address of a = %x\n",p); *(p + 0) = 5; *(p + 1) = 6; *(p + 2) = 7; *(p + 3) = 8; for(i=0; i < 4; i++) { printf("address = %x value = %d\n",(p+i),*(p+i)); } return 0; }
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

