2016-03-24 3 views
0

У меня есть программа, которая выполняет операции над вектором, не изменяя их, а просто считывая один раз, а затем записывая то, что требуется на основе того, что дается. Моя программа работает, но я получаю эту ошибку в конце;Ошибка двойного освобождения или коррупции (! Prev) в моем деструкторе C++

*** Error in './volimage: double free or corruption (!prev): 0x00000000123c10 *** 

Я гугл, и это, кажется, проблема с моим деструктором, но я не могу за жизнь мне найти или решить.

Это деструктор:

VolImage::~VolImage() 
{ 
    std::cout << "Destructor" << std::endl; 
    //deconstructing the vector of slices 
    int i, j, k; 
    for (i = 0; i<size; i++) 
    { 
     for (j = 0; j<height; j++) 
     { 
      delete[] slices[i][j]; 
     } 
     delete[] slices[i]; 
    } 
    slices.clear(); 
} 

Вектор был заселен с помощью следующего:

std::vector<unsigned char**> slices; // data for each slice, in order 

//populating vector 
int i, j, k; 
unsigned char ** rows = new unsigned char*[height]; 
for (i = 0; i < size; i++) 
{ 
    for (j = 0; j < height; j++) 
    { 
     unsigned char* cols = new unsigned char[width]; 
     string num = "%d" + j; 
     fileName = baseName + num + ".raw"; 
     myFile.open(fileName); 
     for (k = 0; k < width; k++) 
     { 
      unsigned char x; 
      myFile >> x; 
      cols[k] = x; 
     } 
     myFile.close(); 
     rows[i] = cols; 
    } 
    slices.push_back(rows); 
} 

Спасибо, поспешный ответ будет оценен, как я должен представить это в ближайшее время

+3

Не должно быть 'rows [j] = cols;' вместо 'rows [i] = cols;'? То есть 'j', а не' i'? – dasblinkenlight

+0

Не видел этого, спасибо, но я все еще получаю проблему с уничтожением –

+0

Почему бы вам просто не использовать вектор вектора векторов? – dreamlax

ответ

2

Вы выделили буфер для хранения указателей на указатели только один раз. Вы должны выделить их для каждой строки.

отметить также, что линия string num = "%d" + j; имеет большой шанс вызвать из-за границы диапазона доступа, потому что "%d" + j эквивалентно &"%d"[j] и только 0 <= j < 3 допускается.

Еще одна вещь: rows[i] = cols; должно быть rows[j] = cols;, поскольку @dasblinkenlight говорит.

Попробуйте это:

//populating vector 
int i, j, k; 
for (i = 0; i < size; i++) 
{ 
    unsigned char ** rows = new unsigned char*[height]; // move this line 
    for (j = 0; j < height; j++) 
    { 
     unsigned char* cols = new unsigned char[width]; 
     std::stringstream ss; 
     string num; 
     ss << j; 
     ss >> num; // convert the integer stored in j to string 
     fileName = baseName + num + ".raw"; 
     myFile.open(fileName); 
     for (k = 0; k < width; k++) 
     { 
      unsigned char x; 
      myFile >> x; 
      cols[k] = x; 
     } 
     myFile.close(); 
     rows[j] = cols; 
    } 
    slices.push_back(rows); 
} 

Добавить #include <sstream> в код, если он не существует, чтобы использовать std::stringstream.

+0

Спасибо, он работает сейчас. На стороне примечания, если бы я хотел подсчитать байты, необходимые для хранения данных, как бы я об этом поступил? sizeOf (slices), кажется, просто возвращает 24 –

-1

Это не прямой ответ, я согласен с ответом @ MikeCAT. Я хочу добавить комментарий, отправленный под soln: (У меня нет достаточного количества сообщений, чтобы опубликовать комментарий напрямую). Please see here почему sizeof(slices) возвращается 24.

Как о чем-то вроде: (width * height * sizeof(slices[0][0][0])) * size, при условии, что slices[0][0][0] существует.

+0

Вот что я в итоге сделал, проблема указателей, указатели тоже должны быть включены –

+0

Пожалуйста, исправьте меня, я мог бы не понимать это: если у вас есть (высота * cols_ptr_size) + (size * rows_ptr_size), который должен дать вам размер суммы указателей? Указатели обычно должны иметь фиксированные размеры (32-разрядные или 64-разрядные, в зависимости от архитектуры, и я принимаю стандартные примеры, а не 32, например 16-разрядные). Извините, если я больше не помогу. – user3554704

+0

Спасибо :) очень полезно –

Смежные вопросы