簡體   English   中英

C ++意外的內存錯誤

[英]C++ unexpected memory error

我在使用簡單的C ++程序時遇到問題,該程序在給定的矩陣中找到最大的子矩陣:

int *A = new int[n*m];
... setting fields for matrix, finding the largest one and etc
... r := size of square-submatrix, max_i := row, max_j := column of the largest
for (i = max_i; i < max_i + r; i++)
{
    for (j = max_j; j < max_j + r; j++)
        cout << A[i * n + j] << "\t";

        cout << "\n";
} 
<memory free>
end of program

一切正常(因此邏輯上沒有問題)-查找正確的子矩陣,prinitng等。

出乎意料(或由於深夜),當我將空閑行delete [] A或delete插入時,所有內容都會因錯誤而崩潰(但仍然可以正確打印結果-因此錯誤必須在此行)。 我試過將其設置為NULL和所有組合。 怎么了?

提前致謝

編輯:

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
int i,j,k; 

int m,n; 
int r; 

cout << "Size of matrix: \nRows: ";
cin >> n;
cout << "Columns: ";
cin >> m;

int *A = new int[n*m];

for (i = 0; i < n; i++)
{
    for (j = 0; j < m; j++)
    {
        A[n*i + j] = rand() % 19 - 9;
        cout << A[n*i + j] << "\t";
    }

    cout << "\n";
}


cout << "Size of submatrix: ";
cin >> r;

int liczba_kwadratow = (m + 1 -r) * (n+1 -r); 

int max = -10000;
int max_i = 0;
int max_j = 0;

int row_iter = 0;
int col_iter = 0;   

for (k = 0; k <liczba_kwadratow; k++)
{
    int sum = 0;
    for ( i = row_iter; i < row_iter + r; i++)
        for ( j = col_iter; j < col_iter + r; j++)
            sum += A[i * n + j];    

    if ( sum > max )
    {
        max = sum;
        max_i = row_iter;
        max_j = col_iter;
    }

    col_iter++;
    if ( row_iter + r > m )
    {
        row_iter++;
        col_iter = 0;   
    }

}

cout << "Field of the largest submatrix  " << r << " of " << r << " equals " << max << "\n";

for (i = max_i; i < max_i + r; i++)
{
    for (j = max_j; j < max_j + r; j++)
        cout << A[i * n + j] << "\t";

    cout << "\n";
}

...works great without delete[] A or delete A

}

至少可以通過我在注釋中告訴您的方法(或使用調試器)來確定問題。 最簡單的方法是改變動態陣列到std::vector ,然后使用成員函數at 然后,您將意識到您在這里拋出了超出范圍的異常:

for (i = 0; i < n; i++)
{
    for (j = 0; j < m; j++)
    {
        A.at(n*i + j) = rand() % 19 - 9; // throws here!!!!, replace n by m
        cout << A.at(n*i + j) << "\t";
    }

    cout << "\n";
}

當輸入為6 5 3時,當您首次嘗試訪問A[30]時會遇到異常,這在delete[] -ing時會讓人頭疼。 現在您可以找出問題所在了,我想...

您在矩陣訪問代碼中倒置了i和j。

基本上公式可以是

current row + current column * number of rows

要么

current row * number of columns + current column

關於代碼和調試的兩個說明:

  1. 使用一個字母的變量可以最大程度地減少鍵盤和手指的磨損,並減少磁盤和內存的使用。 但是,它往往會大大增加調試時間。

  2. 僅僅因為它不會立即崩潰而使代碼正確的假設是絕對錯誤的。 C / C ++是未定義行為的領域(在您的情況下,可能是最常見的行為:在分配的內存之外進行寫操作)。 UB是一件令人討厭的工作,恰恰是因為它會產生任何結果,(包括(通常)明顯沒有后果),只會導致完全正確的代碼在以后崩潰10.000行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM