使用valgrind读取大小为1的俄罗斯方块无效

Invalid read of size 1 in tetris using valgrind

本文关键字:俄罗斯 方块 无效 小为 valgrind 读取 使用      更新时间:2023-10-16

我试图写一个俄罗斯方块动态二维数组行和cols命名的数据;我创建了一个名为edit_2array的函数来复制原来的2D数组,并使每一列更长,其余的用空格填充;

==21909== Invalid read of size 1
==21909==    at 0x100002C0A: Tetris::print() const (main.cpp:300)
==21909==    by 0x1000011CB: test_example() (main.cpp:59)
==21909==    by 0x100001053: main (main.cpp:36)
==21909==  Address 0x10080a9c1 is 1 bytes inside a block of size 2 free'd
==21909==    at 0x1000132F7: free (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==21909==    by 0x100005188: Tetris::edit_2Darray(int, int) (tetris.cpp:214)
==21909==    by 0x1000056EC: Tetris::add_piece(char, int, int) (tetris.cpp:279)
==21909==    by 0x10000118F: test_example() (main.cpp:57)
==21909==    by 0x100001053: main (main.cpp:36)
==21909==  Block was alloc'd at
==21909==    at 0x100012EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==21909==    by 0x10005743D: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==21909==    by 0x1000050DD: Tetris::edit_2Darray(int, int) (tetris.cpp:208)
==21909==    by 0x1000056EC: Tetris::add_piece(char, int, int) (tetris.cpp:279)
==21909==    by 0x10000118F: test_example() (main.cpp:57)
==21909==    by 0x100001053: main (main.cpp:36)
==21909==

这里是我的add_piece函数I size piece和edit_2array ();

private:
int width;
int* heights;
char** data;
Tetris::Tetris(int aWidth) {
  width = aWidth;
  heights = new int[aWidth];
  for (unsigned int i = 0; i < aWidth; i++) {
      heights[i] = 0;
  }
  data = new char* [aWidth];
  for (unsigned int j = 0; j < aWidth; j++) {
      data[j] = new char[1];
      data[j][0] = ' ';
  }
}
void Tetris::add_piece(char c, int m, int n) {
int l = 0;
int max_h = 0;
if (m != 0 &&
    m != 90 &&
    m != 180 &&
    m != 270) {
    cerr << "INCORRECT ANGLE!" << endl;
}
if (n < 0 ||
    n > width-1) {
    cerr << "INCORRECT POSITION" << endl;
}
if (c == 'I') {
    if (m == 0 || m == 180) {
        max_h = get_max_height();
        heights[n] += 4;
        if (heights[n] >= max_h) {
            edit_2Darray(heights[n], heights[n] - max_h);
        }
        data[n][heights[n]-4] = c;
        data[n][heights[n]-3] = c;
        data[n][heights[n]-2] = c;
        data[n][heights[n]-1] = c;
    }
    if (m == 90 || m == 270) {
        l = 0;
        for (unsigned int k = 0; k < 4; k++) {
            if (l < heights[n+k]) {
                l = heights[n+k];
            }
        }
        max_h = get_max_height();
        heights[n] = l+1;
        heights[n+1] = heights[n];
        heights[n+2] = heights[n];
        heights[n+3] = heights[n];
        if (heights[n] >= max_h) {
            edit_2Darray(heights[n], heights[n] - max_h);
        }
        data[n][heights[n]-1] = c;
        data[n+1][heights[n]-1] = c;
        data[n+2][heights[n]-1] = c;
        data[n+3][heights[n]-1] = c;
        }
    }
}
void Tetris::edit_2Darray(int h, int num) {
for (unsigned int i = 0; i < width; i++) {
    char* temp = new char [h];
    for (unsigned int j = 0; j < h; j++) {
        if (j >= (h-num)) {
            temp[j] = ' ';
        }
        else {
            temp[j] = data[i][j];
        }
    }
    delete[] data[i];
    data[i] = temp;
    delete[] temp;
    }
}
void test_example() {
std::cout << "=====================================================================" << std::endl;
std::cout << "test_example()" << std::endl;
Tetris tetris(6);
std::cout << "empty board with width = 6:" << std::endl;
tetris.print();
assert (tetris.get_width() == 6);
tetris.add_piece('O',0,1);
std::cout << "after adding first piece:" << std::endl;
tetris.print();
}

Valgrind告诉您的是,在您的Tetris::edit_2Darray()中,您在第208行分配内存,然后在第214行释放内存(我假设这些是char* temp = new char [h];delete[] temp;,尽管行号不匹配)。然后在Tetris::print()行300(您没有提供)您访问释放的内存。