【问题标题】:Why Does Array With 1 element Allow 2k elements? [duplicate]为什么具有 1 个元素的数组允许 2k 个元素? [复制]
【发布时间】:2012-11-05 04:18:51
【问题描述】:

可能重复:
Why don’t i get “Segmentation Fault”?

为什么这段代码有效?如果第一个元素只包含第一个字符,那么其余字符存储在哪里?如果这是可能的,我们为什么不使用这种方法?

注意第 11 行:静态字符 c[1]。使用一个元素,您可以存储任意数量的字符。当稍后指向它时,我使用静态来使内存位置在函数之外保持活动状态。

#include <stdio.h>

void PutString( const char* pChar ){
   for( ; *pChar != 0; pChar++ )
   {
      putchar( *pChar );
   }
}

char* GetString(){
    static char c[1];
    int i = 0;
    do
    {
        c[i] = getchar();
    }while( c[i++] != '\n' );
    c[i] = '\0';
    return c;
}

void main(){
    PutString( "Enter some text: " );
    char* pChar = GetString();
    PutString( "You typed the following:\n" );
    PutString( pChar );
}

【问题讨论】:

  • 这是未定义的行为。一切都会发生,但所有的赌注都没有了。 (void main 也很奇怪)
  • 还有大约 10,000 人。
  • 换句话说,内存可以被程序访问,因为它认为它没有被使用?
  • @EdS.,嗯,好的。我不知道输入搜索的正确关键字。我担心我可能会问一些已经问过的问题。
  • @adabo: main 应该返回 int

标签: c++ arrays pointers char


【解决方案1】:

C 不检查数组边界,因此不会引发错误。但是,第一个字符之后的字符将存储在程序未分配的内存中。如果字符串很短,这可能会起作用,但足够长的字符串会损坏足够的内存以使进程崩溃。

【讨论】:

  • 在这种情况下,被踩踏的内存很可能是由程序(堆栈空间)分配的,只是写入无效。
  • @EdS。好点,我应该说“未明确分配”。
  • 所以我们的想法是永远不要使用它。明白了。
【解决方案2】:

可以在任何你想写的地方写:

char *bad = 0xABCDEF00;
bad[0] = 'A';

但你不应该。谁知道上面几行代码会做什么?在最好的情况下,你的程序会崩溃。在最坏的情况下,你已经损坏了内存,直到很久以后才会发现。 (祝你好运追踪源头!)

要回答您的具体问题,它“不起作用”。其余字符直接存储在数组之后。

【讨论】:

  • 它不起作用是有道理的。因为它实际上并没有添加新元素。它正在写入未定义的内存。好点子。
【解决方案3】:

您只是非常(不)幸运,您没有覆盖其他一些数据结构。数组绝对不能存储你想要的尽可能多的字符 - 迟早你要么默默地破坏你的内存(在更坏的情况下),要么通过访问你的进程没有映射的内存而遇到段错误。它起作用的事实可能是因为编译器没有在您的c[1] 之后放置任何其他数据。只需尝试添加第二个数组,假设static char d[1];c 之后,然后尝试从中读取 - 您将看到来自c 的第二个字符。

【讨论】:

  • 我明白了。我的淘气行为有时会给我带来麻烦。
【解决方案4】:

C++ 不对数组进行边界检查。这是出于性能原因;检查每个数组索引以查看它是否超出范围会导致不可接受的运行时开销。避免开销一直是 C++ 的设计目标。

如果你想要边界检查,你应该改用std::vector,它通过std::vector::at()提供了一个可选功能。

【讨论】:

  • 感谢您的解释 :)
【解决方案5】:

在这种情况下,行为是未定义的:根据编译器/内存的当前状态/...,它可能看起来运行良好,它可能写入损坏的字符,或者它可能由于一个错误而崩溃。

链接到Electric Fence 或在valgrind 中运行可能有助于在运行时发现此类错误。

【讨论】:

  • 好的,我会调查的。
猜你喜欢
  • 1970-01-01
  • 2021-01-26
  • 2021-10-25
  • 2023-03-26
  • 2019-12-06
  • 2022-08-16
  • 2019-07-07
  • 1970-01-01
  • 2012-08-16
相关资源
最近更新 更多