【发布时间】:2015-01-03 23:55:03
【问题描述】:
我玩了一点C,写了如下代码:
#include<stdio.h>
#include<stdlib.h>
int main() {
char* value = malloc(5 * sizeof(char));
int vect[3];
printf("%d\n", value[135151]);
int i, count = 0;
for(i = 0; i < 135152; i++) {
if(value[i]) {
count++;
printf("position is %d, value is %d and i change it with 42\n", i, value[i]);
value[i] = 42;
vect[count - 1] = i;
}
}
printf("count is %d\n", count);
printf("pointer is at location %p\n", value);
printf("changed values are %d %d %d\n", value[vect[0]], value[vect[1]],
value[vect[2]]);
return 0;
}
经过几次尝试,在我的笔记本电脑上,我发现如果我打印 value[135152] 我得到 segfault,如果我打印 value[135151] 我在标准输出得到 0。
在那之后,我很好奇 查找此间隔中是否存在非零值,并显示 3 个非零值。
之后,我尝试将它们全部修改为 42(我忘了提到在许多程序执行时,20+,即使向量值显示在不同的位置,例如 0xbe7010 或 0x828010,相同的非零相同位置的值仍然存在,这让我明白指针地址是虚拟的(但位置相同))。
之后,我修改了这些值,为了确定,我最后打印了它们,它们显示了 42 个,全部 3 个。但是,在另一个程序执行时,显示了以前的值,就像我没有修改那个内存区域一样。
我会给你我的 3 个连续输出:
0
position is 24, value is -31 and i change it with 42
position is 25, value is 15 and i change it with 42
position is 26, value is 2 and i change it with 42
count is 3
pointer is at location 0x21bb010
changed values are 42 42 42
0
position is 24, value is -31 and i change it with 42
position is 25, value is 15 and i change it with 42
position is 26, value is 2 and i change it with 42
count is 3
pointer is at location 0x20d1010
changed values are 42 42 42
0
position is 24, value is -31 and i change it with 42
position is 25, value is 15 and i change it with 42
position is 26, value is 2 and i change it with 42
count is 3
pointer is at location 0x19d0010
changed values are 42 42 42
你能告诉我为什么这些价值观在改变之后仍然存在吗?
还有,为什么指针地址变了,但内存区是一样的? (我怀疑 C 中的物理内存和虚拟内存之间存在双射函数,每次执行程序时都会发生变化。
感谢您的帮助,并为这堵文字墙感到抱歉!
【问题讨论】:
-
代码应始终检查 malloc(和系列)的返回值,以确保操作成功
-
这一行:'printf("%d\n", value[135151]);'正在访问分配区域之外的内存。这会导致未定义的行为,从而导致段错误事件。
-
这一行:'if(value[i]) {' 当 'i' 大于 4 时,这会导致未定义的行为,这可能会导致 seg 故障事件。执行未定义的行为时会发生什么是“未定义的”。它可以是任何东西,包括你看到的行为。注意:在同一个循环中还有两个未定义行为的实例。与其担心某些随机事件是可重复的,不如修复程序。
-
您是在标准 C 的上下文中询问(在这种情况下,答案是“未定义的行为意味着可能发生奇怪的事情”)还是在整个系统的上下文中(“在这个特定的操作系统上版本,堆的位置是随机的,但之后的一切都是确定性的,并且总是在相对于堆的同一个地方分配东西,所以其他代码相对于你的分配在同一个地方写东西......“)跨度>
标签: c memory allocation