我应该如何担心 valgrind 中阻止的损失

发布于 2024-11-27 05:58:17 字数 2507 浏览 0 评论 0原文

在我的代码中,我有一个类 lipid ,它包含三个珠子:

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;
}

当我尝试创建脂质时,我使用 new 创建三个珠子

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

当我对代码进行 valgrind 时,我得到一个错误,声称有大量块丢失......我应该对此有多担心?我应该声明我正在将beadlipid推入(几个)向量中。

编辑 好的,添加 delete head .. 解决了这个问题,但我仍然有一个痛苦的问题,我有一行:

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

其中 t 是一个 vector 大小为 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)

我怀疑这可能与该行发生的分段错误有关。为什么会出现 new (unsigned long) 以及为什么它会引发分段错误?

In my code I have a class lipid which holds three beads:

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;
}

When I try to create a lipid, I create three beads using new

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

When I valgrind my code, I get an error which claims that there is loads of block missing... How concerned should I be about that? I should state that I'm pushing the beads and the lipids into (several) vectors.

Edit
Ok, adding delete head .. fixed that but I still have an aching problem, I have a line:

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

Where t is a vector<int> of size 3 and beadsBoxes is:

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

This guy gives me 5 times a memory leak error:

==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)

Which I suspect might be related to a segmentation fault which happens is that line. Why does the new (unsigned long) occur and why might it throw a segmentation fault?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

昔日梦未散 2024-12-04 05:58:17

您是否释放了用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

Did you free the objects allocated with new?

For a consistent behavior you should consider using a Constructor and a Destructor:

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
一直在等你来 2024-12-04 05:58:17

当然你有泄漏;你没有释放你的记忆。

在销毁珠子的脂质类中定义一个析构函数,当您将动态分配的脂质存储在向量中时,请使用带有 shared_ptr 或类似的 RAII

更好的是,对所有内容都使用 shared_ptr。或者甚至只使用堆栈;从您给出的设计来看,实际上并不需要指针(特别是裸指针)

Of course you have a leak; you aren't freeing your memory.

Define a destructor in the lipid class that destroys the beads, and when you are storing the dynamically allocated lipids in a vector, use RAII with a shared_ptr or similar.

Better, use shared_ptrs for everything. Or even just use the stack; from the design you have given there's not really any need for pointers anyway (particularly naked pointers)

攒一口袋星星 2024-12-04 05:58:17

不应该首先使用原始指针。
使用智能指针和RAII,这是您遇到的问题的最佳解决方案。使用智能指针将确保一旦没有指针再引用对象,对象本身将负责释放。

看看shared_ptr

就您发布的源代码而言,您永远不会释放动态分配的对象,因此不会释放内存泄漏。

You should not be using Raw pointers in the first place.
Use Smart pointers & RAII, which is the best solution to the problem you are encountering. Using Smart pointers would ensure that the objects themselves will take care of deallocation once no pointer is referencing them anymore.

Have a look at shared_ptr.

As far as the source code you posted, You never deallocate the dynamically allocated objects, and hence the memory leak.

[旋木] 2024-12-04 05:58:17

就像其他海报很好地解释的那样,这些丢失的块是已分配但从未释放的内存,因此在程序的同一运行中永远不会再次使用。

当您尝试长时间运行程序并需要许多新的脂质结构时,这就是一个明确的问题。从软件工程的角度来看,您必须重新分配内存。然而,您似乎是在科学背景下进行编程的,因此我想补充一点,您的结果不受丢失的释放的影响,并且从科学家的角度来看,您可能可以在这里马虎。

Like the other posters excellently explained, these lost blocks are memory that was allocated, but never freed, and thus will never be usable again in the same run of your program.

When you try to run your program for a longer time and need many new lipid structures, this is a definitive problem. From a software engineering POV, you must deallocate your memory. However, you seem to program in a scientific context, and thus I'd like to add that your results are not influenced by the missing deallocation and, from the scientists' POV, you might be able to afford being sloppy here.

清秋悲枫 2024-12-04 05:58:17

从你的代码来看,我认为 Valgrind 试图告诉你的是你有内存泄漏。

在堆上分配一些对象后:

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

您还应该适当地删除它们以恢复内存。事实上,你的脂质类缺少一个你需要清理的析构函数......你可以尝试使用这样的东西:

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;

From your code, I suppose that what Valgrind is trying to tell you is that you have memory leaks.

After allocating some object on the heap:

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

you should also delete them appropriately to recover memory. Indeed, you lipid class is missing a destructor where you do clean up... you might try with something like this:

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

and use it like this:

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

...

//-- when you are done with lipid:
delete l;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文