简体   繁体   English

C ++意外的内存错误

[英]C++ unexpected memory error

I've problem with easy C++ program which finds the largest submatrix in given matrix: 我在使用简单的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

Everything works great (so it's not problem with logic) - finding correct submatrix, prinitng etc. 一切正常(因此逻辑上没有问题)-查找正确的子矩阵,prinitng等。

Unexpectedly (or due to late night) when I put in memory free line delete[] A or delete everything crushes down with errors (but it's still printing result correctly - so the error must be in this line). 出乎意料(或由于深夜),当我将空闲行delete [] A或delete插入时,所有内容都会因错误而崩溃(但仍然可以正确打印结果-因此错误必须在此行)。 I've tried set it to NULL and every combination. 我试过将其设置为NULL和所有组合。 What goes wrong? 怎么了?

Thanks in advance 提前致谢

EDIT: 编辑:

#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

}

The problem can at least be identified via the method(s) I've told you in the comments (or by using a debugger). 至少可以通过我在注释中告诉您的方法(或使用调试器)来确定问题。 Easiest way is changing the dynamical array to a std::vector then use member function at . 最简单的方法是改变动态阵列到std::vector ,然后使用成员函数at You will then realize you get an out of bound exception thrown here: 然后,您将意识到您在这里抛出了超出范围的异常:

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";
}

When input is 6 5 3, then you get an exception when you first try to access A[30] , which gives you a headache when delete[] - ing. 当输入为6 5 3时,当您首次尝试访问A[30]时会遇到异常,这在delete[] -ing时会让人头疼。 Now you can figure out what's wrong I guess ... 现在您可以找出问题所在了,我想...

You inverted i and j in your matrix access code. 您在矩阵访问代码中倒置了i和j。

basically the formula could be 基本上公式可以是

current row + current column * number of rows

or 要么

current row * number of columns + current column

Two remarks on your code and debugging: 关于代码和调试的两个说明:

  1. using one-letter variables minimizes the wear and tear on your keyboard and fingers and reduces disk and memory usage. 使用一个字母的变量可以最大程度地减少键盘和手指的磨损,并减少磁盘和内存的使用。 It tends to increase debugging time dramatically, though. 但是,它往往会大大增加调试时间。

  2. The assumption that the code is OK just because it does not crash immediately is absolutely wrong. 仅仅因为它不会立即崩溃而使代码正确的假设是绝对错误的。 C/C++ is the realm of undefined behaviours (in your case, probably the most common one: writing outside allocated memory). C / C ++是未定义行为的领域(在您的情况下,可能是最常见的行为:在分配的内存之外进行写操作)。 An UB is a nasty piece of work precisely because it can produce any outcome, including (frequently) an apparent absence of consequences, only to cause a perfectly OK bit of code to crash 10.000 lines later. UB是一件令人讨厌的工作,恰恰是因为它会产生任何结果,(包括(通常)明显没有后果),只会导致完全正确的代码在以后崩溃10.000行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM