使用 c++ 偶尔检测到 *** 堆栈粉碎***

Posted

技术标签:

【中文标题】使用 c++ 偶尔检测到 *** 堆栈粉碎***【英文标题】:occasional *** stack smashing detected*** with c++ 【发布时间】:2021-01-30 16:41:00 【问题描述】:

我有以下用于冒泡排序的 C++ 代码。 这段代码编译没有任何错误,但是当我重新编译并运行时,我得到了

***检测到堆栈破坏***:终止

作为一个C++新手,我想知道,为什么运行时会出现这些偶发错误?

void bubbleSort(int eatenPanCakes[10],int arrSize)
 
    int temp=0;
    for(int i=0;i<arrSize-1;i++)
        for (int j = 0; j < arrSize-i; j++)
        
            if (eatenPanCakes[j] > eatenPanCakes[j+1])
            
                temp = eatenPanCakes[j+1];
                eatenPanCakes[j+1] = eatenPanCakes[j];
                eatenPanCakes[j] = temp;
            
               
    

环境:g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

我的代码中有一个错误:for (int j = 0; j+1 &lt; arrSize-i; j++) 将是正确的算法,并且可以正常工作。

Ref-1,Ref-2

【问题讨论】:

外循环第一次迭代中的arrSize-i是什么? 你可以在内循环中使用std::swap 我们需要更多的代码来确定(比如你如何调用你的函数)。但是“堆栈粉碎”看起来像是您试图访问传递数组的越界元素。 【参考方案1】:

您的程序正在访问超出其大小的数组,这是未定义的行为。检查这个for 循环条件:

for (int j = 0; j < arrSize-i; j++)

[我相信,arrSize 的值是 10,因为 eatenPanCakes 数组的类型是 int [10]]

i0arrSize-i 值为10 并且在最后一次迭代中当j 值为9 时,此语句

if (eatenPanCakes[j] > eatenPanCakes[j+1])

访问eatenPanCakes 数组的j+1th 元素,该元素是索引10 处的元素。请注意,大小为10 的数组将具有从09 的有效索引。 相反,for 循环中的条件应该是

for (int j = 0; j < arrSize - i - 1; j++)
                                ^^^

因为jth 元素与数组中它前面的元素进行比较。

【讨论】:

是的,感谢您的详细解释。但我的问题是,这种情况偶尔会发生。有时,它在没有coredump 的情况下运行 @SachithMuhandiram 这是由于未定义的行为。未定义的行为包括它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能恰好按照程序员的意图执行。

以上是关于使用 c++ 偶尔检测到 *** 堆栈粉碎***的主要内容,如果未能解决你的问题,请参考以下文章

调用函数后检测到 C 堆栈粉碎

检测到堆栈粉碎 glGetTexImage

在程序结束时检测到堆栈粉碎

gcc 的 -fstack-protector 选项如何防止堆栈粉碎?

在函数中操作int的数组时堆栈粉碎错误

在有足够空间的情况下加载到数组会导致堆栈粉碎?