Насколько я должен быть обеспокоен потерей, заблокированной в Вальгринде? - PullRequest
2 голосов
/ 02 августа 2011

В моем коде у меня есть класс lipid, который содержит три bead s:

struct lipid{
  particle mainPart;
  bead * head;
  bead * body;
  bead * tail;
  int LID;
  vec direction;
  bead * operator[](int index){
    switch(index){
    case 0: return head;
    case 1: return body;
    case 2: return tail;
    default: return body;
    }
  }
};


struct bead{
  particle mainPart;
  int charge;
  int type;
  double rho;
  double nextRho;
  int LID;
  double U;
  double nextU;
  bool touch;
};


struct particle{
  vec pos;
  vec oldPos;
  vec vel;
  vec oldVel;
  vec F;
  vec oldF;
 };

class vec{
  velarry<double> coor;
  double x;
  double y;
  double z;
}

Когда я пытаюсь создать липид, я создаю три шарика, используя новый

lipid * l = new lipid;
l->head = new bead;
l->body = new bead;
l->tail = new bead;

Когда я проверяю свой код, я получаю сообщение об ошибке, в котором утверждается, что отсутствует множество блоков ... Насколько я должен быть обеспокоен этим? Я должен заявить, что я толкаю bead s и lipid s в (несколько) векторов.

Редактировать Хорошо, добавление delete head .. исправило это, но у меня все еще болит проблема, у меня есть строка:

this->beadBoxes[t[0]][t[1]][t[2]].push_back(b);

Где t - это vector<int> размера 3, а beadsBoxes:

<vector<vector<vector<vector<bead*> > > > beadBoxes;

Этот парень выдает мне 5 раз ошибку утечки памяти:

==22458== 48 bytes in 2 blocks are definitely lost in loss record 11 of 106
==22458==    at 0x4A0666E: operator new(unsigned long) (vg_replace_malloc.c:220)
==22458==    by 0x419A3C: __gnu_cxx::new_allocator<bead*>::allocate(unsigned long, void const*) (new_allocator.h:88)
==22458==    by 0x419A64: std::_Vector_base<bead*, std::allocator<bead*> >::_M_allocate(unsigned long) (stl_vector.h:127)
==22458==    by 0x423E1F: std::vector<bead*, std::allocator<bead*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<bead**, std:\
:vector<bead*, std::allocator<bead*> > >, bead* const&) (vector.tcc:275)
==22458==    by 0x424073: std::vector<bead*, std::allocator<bead*> >::push_back(bead* const&) (stl_vector.h:610)
==22458==    by 0x409664: membrane::updateBox(bead*) (membrane.cpp:874)
==22458==    by 0x40ACA5: membrane::decide(lipid*) (membrane.cpp:793)
==22458==    by 0x40DF01: membrane::rotate() (membrane.cpp:529)
==22458==    by 0x40DFAF: membrane::MCstep() (membrane.cpp:480)
==22458==    by 0x401B54: main (main.cpp:15)

То, что я подозреваю, может быть связано с ошибкой сегментации, которая происходит именно в этой строке. Почему возникает новый (unsigned long) и почему он может вызвать ошибку сегментации?

Ответы [ 5 ]

3 голосов
/ 02 августа 2011

Вы освободили объекты, выделенные new?

Для согласованного поведения вы должны рассмотреть возможность использования Конструктора и Деструктора:

struct lipid{
    // constructor
    lipid() {
        this->head = new bead;
        this->body = new bead;
        this->tail = new bead;
    }
    // destructor
    ~lipid() {
        delete this->head;
        delete this->body;
        delete this->tail;
    }
    ... // rest of the class
2 голосов
/ 02 августа 2011

Конечно, у вас есть утечка;Вы не освобождаете свою память.

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

Лучше используйте shared_ptr s для всего.Или даже просто использовать стек;от дизайна, который вы дали, в действительности нет нужды в указателях (особенно в голых указателях)

2 голосов
/ 02 августа 2011

Вы не должны использовать сырые указатели в первую очередь.
Используйте Умные указатели и RAII , что является лучшим решением проблемы, с которой вы столкнулись. Использование интеллектуальных указателей гарантирует, что сами объекты позаботятся об освобождении, если на них больше не ссылается указатель.

Взгляните на shared_ptr .

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

1 голос
/ 02 августа 2011

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

Когда вы пытаетесь запустить свойПрограмма на более длительное время и требует много новых липидных структур, это определенная проблема.От POV разработки программного обеспечения, вы должны освободить свою память.Тем не менее, вы, кажется, программируете в научном контексте, и поэтому я хотел бы добавить, что ваши результаты не зависят от отсутствующего освобождения, и из POV ученых вы можете позволить себе быть небрежным здесь.

1 голос
/ 02 августа 2011

Я полагаю, что из вашего кода Valgrind пытается вам сказать, что у вас утечки памяти.

После выделения какого-либо объекта в куче:

lipid * l = new lipid;
l->head = new bead;
l->body = new bead;
l->tail = new bead;

вам также следуетdelete их соответственно для восстановления памяти.В самом деле, в вашем классе липидов отсутствует деструктор, в котором вы выполняете очистку ... вы можете попробовать что-то вроде этого:

struct lipid{
  particle mainPart;
  bead * head;
  bead * body;
  bead * tail;
  ~lipid() {
      delete head;
      delete body;
      delete tail;
  }
  ...
};

и использовать его так:

 lipid * l = new lipid;
l->head = new bead;
l->body = new bead;
l->tail = new bead;

...

//-- when you are done with lipid:
delete l;
...