2015-10-17 6 views
-1

Я борется с утечкой памяти, я пишу программу для чтения определенных цветов изображения.Проблема с утечкой памяти C++-программа

Код: http://ideone.com/dcU5Su

Проблема: Я не могу найти источник утечки/утечек памяти.

Что я пытался: Я запустил программу через Valgrind. Среди множества unprocessible информации, ниже приведены ошибки, я разобрал:

  • Invalid write of size 4 [Существовали 3 из них]
  • Conditional jump or move depends on uninitialised value(s)
  • Syscall param write(buf) points to uninitialised byte(s)

Глядя на вышеуказанных ошибок, Я думаю, что проблема связана с неправильной инициализацией. Но я не могу видеть, где.

+0

Пожалуйста, объясните причину, прежде чем вниз голосование вопрос, я новичок здесь, поэтому, пожалуйста, будьте внимательны и помогите мне улучшить. – Harry

+0

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

+1

Пожалуйста, используйте отладчик, прежде чем спрашивать здесь, или жалуйтесь на пустые голоса. –

ответ

1

Вы не должны делать ручное управление памятью следующим образом. Используйте вектор:

#include <iostream> 
#include <sstream> 
#include <vector> 

struct Image { 
    unsigned int l; 
    unsigned int b; 
    unsigned int h; 
}; 

int main() 
{ 
    using namespace std; 

    std::vector<Image> image; 

    std::string line; 
    while(getline(cin,line)) 
    { 
     if(rand()%2) 
     { 
      istringstream iss(line); 

      Image img; 
      while (iss >> img.l >> img.b >> img.h) 
      { 
       image.push_back(img); 
      } 
     } 
    } 
} 

Update

Поскольку вы не обеспечивают обратную связь (почему delete[] оказался внутри цикла в вашем образце), то лучшее, что я могу сделать, это оставить переработан предложение в том числе исправлений/улучшений я хотел бы сделать:

Live On Coliru

#include <iostream> 
#include <sstream> 

#include <cstring> 
#include <cassert> 

struct Image { 
    unsigned int l; 
    unsigned int b; 
    unsigned int h; 
}; 

class Images { 
    private: 
    size_t capacity; 
    size_t size; 

    Image *images; 

    Images& operator=(Images const&); // not supported 
    Images(Images const&);   // not supported 

    void autogrow() { 
     if (size >= capacity) { 
      int newCapacity = capacity * 2; 
      Image* newImage = new Image[newCapacity]; 
      std::cout << "growing " << capacity << " -> " << newCapacity << "\n"; 

      //only available in c++11: 
      static_assert(std::is_pod<Image>::value, "you're screwed"); 
      memcpy(newImage, images, size * sizeof(Image)); 

      capacity = newCapacity; 
      delete[] images; 
      images = newImage; 

     } 
    } 

    public: 
    Images() : capacity(1), size(0), images(new Image[capacity]) { 
     assert(images); 
    }; 
    ~Images() { 
     delete[] images; 
    } 

    Image& insert(Image const& img) { 
     autogrow(); 
     assert(size<capacity); 
     return images[size++] = img; 
    } 

}; 

int main() 
{ 
    using namespace std; 

    Images collection; 

    std::string line; 
    while(getline(cin,line)) 
    { 
     if(true) { 
      istringstream iss(line); 

      Image cur; 
      while (iss >> cur.l >> cur.b >> cur.h) { 
       collection.insert(cur); 
      } 
     } 
    } 
} 

Отпечатки, например.

od /dev/urandom -Anone -t u4 -w36 | head -1000 | ./a.out 
growing 1 -> 2 
growing 2 -> 4 
growing 4 -> 8 
growing 8 -> 16 
growing 16 -> 32 
growing 32 -> 64 
growing 64 -> 128 
growing 128 -> 256 
growing 256 -> 512 
growing 512 -> 1024 
growing 1024 -> 2048 
growing 2048 -> 4096 
+0

Все еще глядя на ваш код, чтобы дать более конкретный намек, что было не так (https://www.livecoding.tv/sehe/, ваш SSCCE был сломан) – sehe

+0

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

+2

@Harry Почему бы вам не захотеть использовать 'std :: vector'? –

0

Я думаю, когда while (iss >> image[j].l >> image[j].b >> image[j].h) выполняется при прохождении через вторую итерацию внешней время цикла, то image указатель не действует, так как вы удалили его в предыдущей итерации.

Таким образом, после того, как delete[] ИНГ image во второй раз (после внутренней while петли), вы должны сбросить переменные (как если бы вы были повторно entring внешнего while цикла в первый раз.

// reset 
delete[] (image); 
capacity = 1; 
size = 0; 
j = 0; 
image = new Image[capacity]; 

Или вы должны поместить этот блок «сброса» только в начале внешнего while (и избавиться от инициализации перед ним).

Я не знаю логики всей программы, но я бы предположим, что это желаемое поведение ...

EDIT: так что проблема может быть решена путем перемещения size++; чуть выше if (size >= capacity) (престижности @sehe для нахождения происхождения нарушения памяти :))

size++; 
if (size >= capacity) 
{ 
+0

I подумал, что образец слишком сломан, чтобы сделать реальные выводы, но я реорганизовал его в рабочий беспорядок в своем ответе :) – sehe

+0

, пожалуйста, посмотрите здесь: http://ideone.com/dcU5Su – Harry