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

Invalid read of size 1 in tetris using valgrind

我正在尝试编写一个由行和列命名的数据的俄罗斯方块动态二维数组;我创建了一个名为 edit_2Darray 的函数来复制原始二维数组并使每一列更长,其余的我用 space;

填充
==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 尺寸和 edit_2Darray();

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 行(你没有提供)你访问释放的内存。