【问题标题】:Is it a case of memory overflow or overwrite in C? [duplicate]这是C中内存溢出或覆盖的情况吗? [复制]
【发布时间】:2016-06-07 01:35:30
【问题描述】:

这是我的代码。我正在玩我写的一小段代码。

即使指针的字符数组有 2 个元素,我也可以使用该字符数组的指针地址间接写入内存位置,即使它只有 2 个元素。

我可能想错了,或者因为我今天用力过猛。

我希望有人能对此有所了解。

#include <stdio.h>

int main(void)
{
    char a[] ="GKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3u";
    char b[] ="GKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3uGKdkOSwdDMjQKT6fgZ3u";
    char *line_store[2];
    *(line_store) = a;
    *(line_store + 2) = b;
    printf("%s\n\n", *(line_store));
    printf("%s\n\n", *(line_store+1));
    printf("%s\n\n", *(line_store+2));
    return 0;
}

【问题讨论】:

  • @kaylum 我真的尽量不创建任何重复的线程,我坚信,这不是一个重复的案例,而是一个稍微细微的版本,也许吧?
  • 为什么?您读取/写入超出范围的数组元素。这有什么不同或微妙?底线是它是未定义的行为。您对它会以某种方式失败的期望是不正确的。当 UB 发挥作用时,你不能有任何这样的期望。
  • 描述性是一个更好的词。那篇文章有一个最小的例子,我相信我通过我的代码更好地解释了我的问题,并且底线不限于此处未定义的行为。
  • 嗯?不明白你的意思。关键问题是越界访问。您是在询问未定义行为的定义吗?请准确说明您想知道的内容。
  • line_store 可以包含 2 个元素。写 *(line_store + 2) 是未定义的行为。一旦你的一行代码支持了 UB,你的整个程序就变成了 U(未定义)。

标签: c arrays pointers


【解决方案1】:

您的代码有效,因为 C 不对您的数组进行任何边界检查。您正在写入超出分配的最后一个元素,这会导致它写入内存中未分配的空间。这可能是偶然的,后续运行理论上可能会崩溃,或覆盖其他有效的内存段,具体取决于在更大的程序中执行此操作的位置和方式。

【讨论】:

  • 哦,是的,边界检查!我希望在不使用编译器帮助的情况下使这段代码失败,或者这不是一个好的选择,而是我应该依赖编译器标志?。
  • 你是想让程序崩溃吗?
  • 我的意思是我应该让它崩溃,对吧?因为这看起来不太好,不是吗?至少编译(可能是因为某些编译器标志)应该失败。
  • @Avineshwar 不。正如我已经向您解释过的,“它应该崩溃”是一个不正确的期望。这是未定义的行为。尽管它可能会在某些程序中崩溃,但某些编译器在某些日子没有定义崩溃,并且编译器/操作系统没有义务确保它崩溃。
  • @kaylum 我想我设法通过这里的讨论和对建议帖子的引用得到了答案。
猜你喜欢
  • 1970-01-01
  • 2017-08-20
  • 2012-04-02
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 2014-07-07
相关资源
最近更新 更多