Двойной бесплатный корпус - PullRequest
0 голосов
/ 22 июля 2010

У меня есть сетка вызовов класса. Класс содержит два двумерных массива символов для хранения сетки ... Класс имеет две функции для создания памяти для сетки и освобождения памяти для сетки.

Grid.h

private:
char **gridOne;
char **gridTwo;

Grid.cpp

void Grid::allocateGridMem()
{
   _gridOne = new char*[gridRowCount()];
   _gridTwo = new char*[gridRowCount()];

   for(int i =0; i < gridColumnCount(); ++i){
      *(_gridOne + i) = new char[gridColumnCount()];
      *(_gridTwo + i) = new char[gridColumnCount()];
   }
}

void Grid::dealocateGridMem()
{
   if(_gridOne != 0)
   {
      for(int i =0; i < gridRowCount(); ++i){
         delete [] *(_gridOne + i);
      }
      delete [] _gridOne;
      _gridOne = 0;
   }

   if(_gridTwo != 0)
   {
      for(int i =0; i < gridRowCount(); i++){
         delete [] *(_gridTwo + i);
      }
      delete [] _gridTwo;
      _gridTwo = 0;
   }
}

Проблема происходит в освобождении памяти, которое я получаю следующую ошибку.

    *** glibc detected *** ./a.out: double free or corruption (out): 0x088c9318 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xb756c591]
    /lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0xb756dde8]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb7570ecd]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb775c741]
    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb775c79d]
    ./a.out[0x804a7b9]
    ./a.out[0x8049cb6]
    ./a.out[0x804b8f3]
    ./a.out[0x804c06a]
    ./a.out[0x804b71d]
    ./a.out[0x80498eb]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7517bd6]
    ./a.out[0x8049521]
    ======= Memory map: ========
    08048000-0804f000 r-xp 00000000 08:02 920728     /home/a.out
    0804f000-08050000 r--p 00006000 08:02 920728     /home/a.out
    08050000-08051000 rw-p 00007000 08:02 920728     /home/a.out
    088c7000-088e8000 rw-p 00000000 00:00 0          [heap]
    b7300000-b7321000 rw-p 00000000 00:00 0 
    b7321000-b7400000 ---p 00000000 00:00 0 
    b7500000-b7501000 rw-p 00000000 00:00 0 
    b7501000-b7654000 r-xp 00000000 08:02 19796293   /lib/tls/i686/cmov/libc-2.11.1.so
    b7654000-b7655000 ---p 00153000 08:02 19796293   /lib/tls/i686/cmov/libc-2.11.1.so
    b7655000-b7657000 r--p 00153000 08:02 19796293   /lib/tls/i686/cmov/libc-2.11.1.so
    b7657000-b7658000 rw-p 00155000 08:02 19796293   /lib/tls/i686/cmov/libc-2.11.1.so
    b7658000-b765b000 rw-p 00000000 00:00 0 
    b765b000-b7678000 r-xp 00000000 08:02 19791955   /lib/libgcc_s.so.1
    b7678000-b7679000 r--p 0001c000 08:02 19791955   /lib/libgcc_s.so.1
    b7679000-b767a000 rw-p 0001d000 08:02 19791955   /lib/libgcc_s.so.1
    b767a000-b767b000 rw-p 00000000 00:00 0 
    b767b000-b769f000 r-xp 00000000 08:02 19796301   /lib/tls/i686/cmov/libm-2.11.1.so
    b769f000-b76a0000 r--p 00023000 08:02 19796301   /lib/tls/i686/cmov/libm-2.11.1.so
    b76a0000-b76a1000 rw-p 00024000 08:02 19796301   /lib/tls/i686/cmov/libm-2.11.1.so
    b76a1000-b778a000 r-xp 00000000 08:02 28708531   /usr/lib/libstdc++.so.6.0.13
    b778a000-b778b000 ---p 000e9000 08:02 28708531   /usr/lib/libstdc++.so.6.0.13
    b778b000-b778f000 r--p 000e9000 08:02 28708531   /usr/lib/libstdc++.so.6.0.13
    b778f000-b7790000 rw-p 000ed000 08:02 28708531   /usr/lib/libstdc++.so.6.0.13
    b7790000-b7797000 rw-p 00000000 00:00 0 
    b77a5000-b77a8000 rw-p 00000000 00:00 0 
    b77a8000-b77a9000 r-xp 00000000 00:00 0          [vdso]
    b77a9000-b77c4000 r-xp 00000000 08:02 19791897   /lib/ld-2.11.1.so
    b77c4000-b77c5000 r--p 0001a000 08:02 19791897   /lib/ld-2.11.1.so
    b77c5000-b77c6000 rw-p 0001b000 08:02 19791897   /lib/ld-2.11.1.so
    bf83a000

-bf84f000 rw-p 00000000 00:00 0          [stack]
Aborted

Я проверил все мои указатели на то, что они не меняются на что-то другое при исполнении, и что каждая проверка и баланс, о которых можно подумать, происходит в обряде. Я выдергивал свои волосы последние несколько часов, но все еще ничего.

Я запускаю это с gcc в системе Ubuntu 10.

Следует также отметить, что я изменил имена и т. Д. Для целей этого поста и включил только код, который, как мне кажется, имеет значение.

EDIT:

Исправлена ​​проблема с синтаксисом, однако в исходном коде это было просто набрано, и я не прочитал корректуру.

Любая помощь очень ценится и стоит золотой звезды в моей книге. Я очень опытный пользователь GDB и использовал это с этой проблемой, но я думаю, что это проблема, возможно, во внешней библиотеке. Я не вижу никаких проблем с памятью и тем, как она определяется, просто надеясь, что кто-то видел что-то подобное. Для всех целей этот код подходит.

Ответы [ 5 ]

3 голосов
/ 22 июля 2010

изменение

for(int i =0; i < gridColumnCount(); ++i){
   _gridOne = new char[gridColumnCount()];
   _gridTwo = new char[gridColumnCount()];
}

до

for(int i =0; i < gridRowCount(); ++i){
   _gridOne[i] = new char[gridColumnCount()];
   _gridTwo[i] = new char[gridColumnCount()];
}

Кроме того, не делай

*(array + i)

но

array[i]
1 голос
/ 22 июля 2010

Имеет ли ваш класс Grid конструктор копирования и оператор присваивания ? В противном случае, если вы скопируете такие объекты, эта ошибка будет тем, что произойдет.

Я предлагаю вам прекратить выполнять ручное управление ресурсами и сделать Grid тонкой двумерной оболочкой вокруг std::vector<char>, которая управляет памятью.

1 голос
/ 22 июля 2010

Вероятно, это должно быть _gridOne[i] вместо _gridOne внутри цикла allocateGridMem.Но, пожалуйста, избегайте таких низкоуровневых операций, когда это возможно, и используйте высокоуровневый компонент, такой как boost::numeric::ublas::matrix.

0 голосов
/ 22 июля 2010

Используйте STL и векторы:

class Grid
{
    std::vector<std::vector<char> >    grid1;
    std::vector<std::vector<char> >    grid2;

    public:
       Grid(int col,int row)
           : grid1(col, std::vector<char>(row))
           , grid2(col, std::vector<char>(row))
        {}
 };

Все сделано.

Если вы хотите получить модный взгляд на Boost Matrix.

0 голосов
/ 22 июля 2010

sudo apt-get install valgrind, запуск valgrind myprogram и 99% ошибок выделения памяти становятся очевидными.

По крайней мере одна из проблем заключается в том, что вы назначаете строку (должно быть _gridOne[i]) поверхуказателя массива.Компилируйте с -Werror -Wall -W, и многие подобные ошибки станут очевидными во время компиляции.

...