C++二维 vector 导致缓冲区溢出

标签 c++ ubuntu multidimensional-array vector

我制作了一个“生命游戏”程序,您可以在其中插入大小、活细胞和游戏速度。不幸的是我的程序不工作。我将问题缩小到 vector> rules 函数,我想它必须做一些数字太高或太低的事情。 这段代码可以编译,但是一旦我进入规则部分,我就会收到以下错误:

==3944==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000000100 at pc 0x000000518258 bp 0x7ffdd648f5d0 sp 0x7ffdd648f5c8

我试图将无符号整数值更改为普通整数,但随后弹出警告。我让其他一切正常工作,但我似乎无法找到一种方法来完成这项工作。 感谢您的帮助!

如果有帮助,我会在 ubuntu 操作系统上工作,使用 clang 作为我的编译器。

#include <iostream>
#include <stdexcept>
#include <cmath>
#include <vector>
#include <unistd.h>
using namespace std;

void rowsandcolumns (int row, int column) {

    int rowwhole = floor (row);
    int columnwhole = floor (column);

    if (row <=0 || column <=0 || row != rowwhole || column != columnwhole) {
        throw runtime_error ("Nur positive ganze Zahlen erlaubt");
    }
}

vector<vector<int>> rules (vector<vector<int>> cleanBoard, int row, int column, vector<vector<int>> secondBoard) {

    for (int i = 1; i <= row+1; i++) { 

        for (int j = 1; j <= column+1; j++) {

            int x;
            int a = cleanBoard [i-1][j-1];
            int b = cleanBoard [i][j-1];
            int c = cleanBoard [i+1][j-1];
            int d = cleanBoard [i-1][j];
            int e = cleanBoard [i+1][j];
            int f = cleanBoard [i-1][j+1];  
            int g = cleanBoard [i][j+1];    
            int h = cleanBoard [i+1][j+1];
            int mitte = cleanBoard [i][j];
            cout << cleanBoard[i][j];

            x = a+b+c+d+e+f+g+h;

            if (x < 2 && mitte == 1) {

                secondBoard [i][j] = 0;
            }

            else if ((mitte == 1 && x == 2) || x == 3) {

                secondBoard [i][j] = 1;
            }

            else if (mitte == 1 && x > 3) {

                secondBoard [i][j] = 0;
            }

            else if (mitte == 0 && x == 3) {

                secondBoard [i][j] = 1;
            }
            else break;
        }
    }

    return secondBoard;
}

double gamespeed() {

    double speed;
    cout << "Geben sie nun die Geschwindigkeit ein, mit welcher sich 'Game of Life' entwickeln soll. (Empfohlen 0.5 Sekunden bis 2 Sekunden)\n";
    cin >> speed;
    cout << '\n';
    return speed;
}

int main () {

    //initialisierung der wichtigen Variablen
    int alive = 1;
    int dead = 0;
    double row, column, x, y, speed;

    //Eingabe der Reihen und Spalten und Check, ob dies erlaubt ist
    cout << "Geben sie die Dimensionen row (Zeilen) und column (Spalten) für Conways 'Game of Life' an! (Ganze positive Zahlen)\n";
    cin >> row >> column;
    rowsandcolumns(row, column);

    //Erstellung des nxm Feldes
    vector<int> v(column);
    vector<vector<int>> cleanBoard(row, v);

    //Erstellung des Spielfeldes, wo jede Zelle tot ist
    for (int i = 0; i < row; i++) {      
        for (int j = 0; j < column; j++) {
            cleanBoard[i][j] = dead;
            cout << cleanBoard[i][j] << " ";
        }
        cout << endl;
    }

    //Eingabe der eigenen lebenden Zellen und Check, ob eine richtige Zahl eingegeben wurde
    do {    
        cout << "Geben sie nun die Koordinaten ein, an welcher Stelle sie eine lebende Zelle platzieren wollen. Vorher Zeile, dann Spalte! (Geben sie mindestens einmal 0 ein, um das Spiel zu starten)\n";
        cin >> x >> y;

        int newx = floor (x);
        int newy = floor (y);
        if (x < 0 || y < 0 || newx != x || newy != y || x > row || y > column) {
            throw runtime_error ("Nur positive ganze Zahlen zwischen 1 und den eingegebenen Dimensionen möglich.");
        }
        if (x != 0 || y != 0){
            x -= 1;
            y -= 1;
            cleanBoard[x][y] = alive;
            for (int i = 0; i < row; i++) {      
                for (int j = 0; j < column; j++) {
                    cout << cleanBoard[i][j] << " ";
                }
                cout << endl;
            }
            x += 1;
            y += 1;
        }
    } while (x != 0 || y != 0);

    cout << '\n';

    //Zeiteingabe
    speed = gamespeed();

    //Start des Spiels und Spielablauf
    vector<vector<int>> secondBoard;
    for (int u = 1; 0 < u; u--) {
        rules(cleanBoard, row, column, secondBoard);
        for (unsigned i = 0; i < secondBoard.size(); i++) {      
            for (unsigned j = 0; j < secondBoard[i].size(); j++) {
                cout << secondBoard[i][j] << " ";
            }
            cout << endl;
        }
        cleanBoard = secondBoard;
        cout << "STRG+Z zum abbrechen";
        usleep(speed*1000);
    }

    return 0;

}

最佳答案

问题出在你有两个 for 循环的规则函数中。

for (int i = 1; i <= row+1; i++) { 
  for (int j = 1; j <= column+1; j++) {

一些对 cleanBoard 的调用是越界的。如果 rows 是 3,int 我将继续直到它不再 <= 3+1。所以,最后一个循环将有 int i = 4。这一行...

int c = cleanBoard [i+1][j-1];

您正在尝试执行 cleanBoard[5][j-1],但 cleanBoard[5] 不存在,它仅初始化到 [row][column]。修复将是这样的:

for (int i = 1; i <= row-1; i++) {
  for (int j = 1; j <= column-1; j++) {

编辑:某处还有另一个错误,不过我不太确定如何修复它。我得到的错误是

Program received signal SIGSEGV, Segmentation fault.
0x000055555555631a in std::vector<int, std::allocator<int> >::operator[] (
    this=0x18, __n=1) at /usr/include/c++/9/bits/stl_vector.h:1043
1043        return *(this->_M_impl._M_start + __n);

关于C++二维 vector 导致缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58888686/

相关文章:

c++ - 如何使用类型特征使这种数组到指针的转换明确?

c++ - 为什么 Visual Studio 2010 会给我此代码的语法错误?

树莓派 3 上的 Ubuntu MATE 架构

php - 通过在多维数组中搜索标题返回值

python - 在 numpy Capi 中创建动态数组

javascript - 循环多维数组以生成新数据并在 Node js/javascript 中附加新键值

c++ - 获取C++中终端运行命令的返回值

Linux 中的 C++ Stream 接口(interface)

ubuntu - 如何重置 Google Cloud SDK 的虚拟机?

linux - 从 80 端口的 Eclipse 启动 Tomcat ( Linux )