"stack smashing detected"的原因是什么?

What is the reason for "stack smashing detected"?

我是编程新手,目前正在研究地址类型转换。我似乎不明白为什么我会得到这个:*** stack smashing detected ***: terminated Aborted (core dumped) 当我 运行 以下代码时??

#include<iostream>
using namespace std;

void updateValue(int *p){
    *p = 610 % 255;
}

int main(){
    char ch = 'A';
    updateValue((int*)&ch);
    cout << ch; 
}

以下是我对代码的理解:

ch 的地址类型转换为 int* 并传递给函数 updateValue()。现在,在 updateValue() 堆栈中,创建了一个指向 ch 的整数指针 p。当 p 被取消引用时,它将 ch 解释为 int 并读取 4(或 8)字节的连续内存而不是 1。因此,'A'(65) 以及一些垃圾值得到分配给 610%255 即 20.

但是我不明白,哪里出了问题?

But I don't understand, what and where things are going wrong?

在此声明中

*p = 610 % 255;

不属于char类型对象ch的内存被覆盖。那不是对象 ch 占用的一个字节,而是覆盖了 4 个字节,对应于为 int 类型的对象分配的内存。

when p is dereferenced, it interprets ...

当您通过重新解释的 p 间接访问错误类型的对象时,程序的行为是未定义的。

what and where things are going wrong?

当您将指向一种类型的指针重新解释为指向不相关类型的指针时,事情就开始出错了。

一些经验法则:

  • 在您知道它的作用之前,不要使用重新解释转换。它们很难做对,而且很少有用。
  • 如果会导致未定义的行为,请不要使用重新解释转换。
  • 根本不使用 C-style 转换。
  • 如果您认为需要重新解释 cast,请退后几步,考虑为什么您认为需要它。

问题是你类型转换一个char*到一个int*然后取消引用p 导致 未定义的行为 .

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。在您的情况下,程序可能会崩溃。

例如,here the program crashes, but here它不会崩溃。

因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。


1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.