在 C++ 中检测到堆损坏错误

Posted

技术标签:

【中文标题】在 C++ 中检测到堆损坏错误【英文标题】:Heap corruption detected error in C++ 【发布时间】:2018-08-27 07:53:42 【问题描述】:

这是我的代码:

#include<iostream>
#include<cstdlib>

using namespace std;

int main() 
    int** arr=NULL;
    int num=0;
    cin >> num;
    int* big=NULL;
    arr = new int*[num];
    for (int i = 0; i < num; i++) 
        arr[i] = new int[5];
    
    big = new int[num];

    for (int i = 0; i < num; i++) 
        for (int j = 0; j < 5; j++) 
            while (1) 
                cin >> arr[i][j];
                if (arr[i][j] >= 0 && arr[i][j] < 100)
                    break;
            
        
    

    for (int i = 0; i < 5; i++) 
        big[i] = 0;
    

    for (int i = 0; i < num; i++) 
        for (int j = 0; j < 5; j++) 
            if (big[i] < arr[i][j]) 
                big[i] = arr[i][j];
            
        
    

    for (int i = 0; i < num; i++) 
        cout << "Case #" << i + 1 << ": " << big[i] << endl;
    

    delete[]big;
    for (int i = num-1; i>=0; i--) 
        delete[]arr[i];
    
    delete[]arr;

    return 0;

当我运行此代码时,它说存在堆损坏错误(检测到堆损坏)。我认为这意味着我的代码中的“新”或“删除”部分存在一些错误,但我找不到它们。希望有人回答。谢谢。

【问题讨论】:

我可以毫无问题地在cpp.sh 编译您的代码。你用的是什么编译器?我们需要更多信息。还有什么是输入,输出应该是什么? @YesThatIsMyName g++、clang 和 icc 正在编译这个(使用 -Wall)而没有警告。 一个好的现代 C++ 编码实践是避免newdelete,并尽可能使用标准库,例如std::vectorunique_ptr. big = new int[num]; for (int i = 0; i &lt; 5; i++) big[i] = 0; - 所以如果num 小于 5,你就有一个错误。 Heap corruption: What could the cause be?的可能重复 【参考方案1】:

错误在这里:

big = new int[num];
...
for (int i = 0; i < 5; i++) 
    big[i] = 0;

因此,当您的 num 小于 5 时,您就是在数组外写入。

无论如何,您都在使用 C++,因此请使用矢量来完成此类任务。

#include<iostream>
#include<cstdlib>
#include<vector>

using namespace std;

int main() 
    vector<vector<int>> arr;
    int num=0;
    cin >> num;
    arr.resize(num, vector<int>(5));

    for (auto &row : arr) 
        for (auto &cell : row) 
            while (1) 
                cin >> cell ;
                if (cell >= 0 && cell < 100)
                    break;
            
        
    

    vector<int> big(arr.size());
    for (int i = 0; i < arr.size(); i++) 
        for (auto &cell : arr[i]) 
            if (big[i] < cell) 
                big[i] = cell;
            
        
    

    for (int i = 0; i < num; i++) 
        cout << "Case #" << i + 1 << ": " << big[i] << endl;
    

    return 0;

【讨论】:

是的,你是对的。该部分会导致堆损坏错误。非常感谢。【参考方案2】:

在您的代码中的许多地方,您使用从 0 到 5 的索引来索引您的 big 数组,而该数组是使用用户输入分配的,例如,如果用户输入是 4,那么您的代码是未定义的行为.

如果你使用 c++,你不应该手动分配数组,而是使用std::vector,它会为你管理内存,所以你不必newdelete自己记忆。

使用std::vector,您的代码看起来有点像这样。

std::vector<std::vector<int>> arr;
std::vector<int> big;
cin>>num;
arr.resize(num, std::vector<int>(5));
big.resize(5);

您还可以在边界检查时使用at 方法访问元素,并使用size 方法获取数组元素的数量。

【讨论】:

以上是关于在 C++ 中检测到堆损坏错误的主要内容,如果未能解决你的问题,请参考以下文章

字符串的动态数组,但我检测到堆损坏

检测到堆损坏(动态数组)

在 vs2008 中升级后检测到堆损坏

释放 2D 数组 - 检测到堆损坏

检测到堆损坏 - 仅限 iPhone 5S

将项目从 vc6 升级到 vc9 后检测到堆损坏