gpt4 book ai didi

c - 为什么二维数组在将其中一行复制到以前未定义的位置时会发生变化?

转载 作者:行者123 更新时间:2023-11-30 19:26:20 25 4
gpt4 key购买 nike

查看以下代码示例,其中我故意将 a[2] 复制到不存在的 p[2] (仅 p[1] 和 p[0] 存在)
我猜这应该对数组 a 没有影响。

但是当我打印'r'引用的数组时
输出如下

00  
34

-133280
34

如果我要么完全删除
p[2]=a[2]   

或更正这两个陈述

IE
p[0]=a[0]  
p[1]=a[1]

然后错误消失了,我得到了预期的输出

这是审查的代码
 int a[2][2]={{1,2},{3,4}};
int * p[2];
int (*r)[2];
p[1]=a[1];
p[2]=a[2]
r=a;

我期望的输出
 for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
printf("%d",p[i][j]);
printf("\n");
}
printf("NExt\n");

for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
printf("%d",r[i][j]);
printf("\n");
}

成为
00  
34

12
34

提前致谢

最佳答案

首先,你为什么期待打印p的结果?成为

00
34

有异常(exception),但未初始化的内存不能保证一开始就包含 0。更重要的是,随机指针(在您的情况下是 p[0])尤其不能保证指向包含 0 的内存!我期望的结果是
meaningless pseudo-random numbers
34

其次,当您写入不属于您的内存时,例如
p[2] = a[2];

这是一件非常糟糕的事情,几乎任何事情都可能发生。

这里有两件事不会发生:
  • 编译器检测到您正在写入不属于您的内存,并给您一条错误消息。
  • 编译器检测到您正在写入不属于您的内存,并确保在任何地方都没有写入任何内容。

  • 不,通常发生的情况是
  • 尝试写入您不拥有的内存,结果非常糟糕。

  • 你说,“我猜这应该对数组 a 没有影响。”我不知道你为什么这么猜。我们有两个事实:

    (a) 程序正在写入数组 p 之外的某些内存部分.我们不知道它实际写在哪里;它几乎可以在任何地方。

    (b) 数组 a正在神秘地写入。

    鉴于这两个事实,你能猜出糟糕的写作实际上可能在哪里写吗?

    另见 this answer对于一个不相关的问题,特别是关于“如果有内存并且我们确实获得许可并且它没有被用于其他任何事情,那么该程序似乎可以工作 - 现在”的段落。

    附录:在评论中,您问“但是在连续编译中,被覆盖的内存不应该不同”。有两种方法可以回答这个问题。
  • 作为 C 程序员(实际上是任何类型的程序员),了解当您从事未定义的行为时,任何事情都可能发生,这一点非常重要。让我重复一遍:任何事情都可能发生。让我再重复一遍:任何事情都有可能发生!结果不一定是合理的。他们不必说得通。它们不必局限于您可能预期会出错的事情。如果您认为它们是随机的,它们不必因运行而异。如果您认为它们是一致的,它们不必每次运行都保持不变。您根本无法对可能发生或可能不会发生的事情做出任何预测。最好的解决方案——唯一的解决方案——首先是不要从事未定义的行为。
  • 有时,未定义行为的结果令人惊讶。 (几乎没有什么让我感到惊讶,但有时一些程序员会感到惊讶。)如果对编译器和目标体系结构有足够的了解,只要有足够的时间和精力,通常可以对观察到特定结果的原因做出令人满意的解释。但是由于我对您的编译器和目标架构一无所知,并且(对不起)我几乎没有时间回答这个问题,所以我不会推测为什么(在这种情况下)它们会导致和你预期的不一样。

  • 我将以我最喜欢的类比结束,尽管当您刚刚问的是为什么连续运行的结果与您预期的不同时,它会更好地工作:

    Yesterday I was working on my car. I took off the front wheel to work on the brakes, and when I put the wheel back on, I forgot to fasten the lugnuts. I went for a drive, and at 60 mph, the front wheel flew off, and the car veered to the side, and I crashed into the ditch at the side of the road.

    Today when I went to repair the damage, I had to take the front wheel off again. When I put it back on, I forgot to fasten the lugnuts again. But this time, when I went for a drive and the front wheel flew off, the car veered to the other side, and I crashed head-on into a semi.

    Why did I get different results? I expected them to be the same.



    现在,这似乎是一个荒谬的类比,但实际上,对于我和任何有经验的 C 程序员来说,当有人问为什么一个程序在从事未定义的行为之后,生成或没有生成时,这听起来是多么荒谬可预测的结果。是的,计算机和计算机程序通常是确定性设备,但正如我之前所说,当您从事未定义的行为时, 任何东西可以发生。

    关于c - 为什么二维数组在将其中一行复制到以前未定义的位置时会发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57543936/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com