【问题标题】:String memory allocation in C [closed]C中的字符串内存分配[关闭]
【发布时间】:2013-09-27 15:44:08
【问题描述】:

谁能澄清一下?

char str[1];
strcpy(str, "HHHHHHHHHHHH");

在这里我声明了一个大小为 1 的 char 数组,但程序不会崩溃,直到我输入超过 12 个字符并且我只有一个大小为 1 的数组。为什么?

【问题讨论】:

  • 恭喜你找到了 UB !
  • 这是related post。情况并不完全相同,但对发生的事情的解释相同。
  • @POW,用这个缩写是为了让人问“UB的定义是什么”?这很卑鄙。我喜欢它。
  • @Glove 选一本好书
  • 我们几乎每天都有这类问题,我想。提问前请先搜索网站。 C no out of bounds error 的可能重复项

标签: c arrays memory char


【解决方案1】:

这段代码有未定义的行为,因为它将多个元素写入str。它可以做任何事情有责任确保您只写入您拥有的内存。

【讨论】:

  • 我只是好奇谢谢!
  • @Glove 这个community WIKI 可能有用。
【解决方案2】:

这是未定义的行为。在实践中,您会覆盖某些内容的内存内容。在这种情况下,如果该数组是局部变量,则该数组将进入堆栈。很可能您的 CPU 架构中堆栈会向下增长,因此您开始覆盖其他局部变量、保存的寄存器值和函数调用的返回地址等内容。

您可能首先覆盖了没有立即生效的内容,或者您​​没有注意到效果。这可能是一个尚未初始化的局部变量,或者是一个局部变量或保存的寄存器值,在您覆盖它之后实际上并未使用它。

然后当你增加溢出长度时,你可能损坏了函数返回地址,然后当你从函数返回时实际上发生了崩溃。如果您有任何其他内存地址,即指针,则崩溃也可能是因为您试图访问损坏的指针指向的值。

最后,如果你将溢出大小增加到足够大,字符串复制最终会直接写入允许的区域之外并导致立即崩溃(假设 CPU 和操作系统具有这种内存保护,而不是一些古老的或嵌入式系统)。但这可能不是这里的原因,因为您在崩溃前只写了 14 个字节。

但请注意,从 C 语言的角度来看,上述内容有点毫无意义,未定义的行为,如果您更改程序中的任何内容、编译器选项或输入数据,它通常会发生变化。这会使内存损坏错误很难找到,因为添加调试内容通常会使问题“消失”(更改或隐藏症状)。

【讨论】:

    猜你喜欢
    • 2021-08-21
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多