将项目推送到 STL 容器后出现段错误

发布于 2024-07-16 11:33:37 字数 304 浏览 7 评论 0原文

typedef struct temp  
{  
        int a,b;  
        char  *c;  
        temp(){ c = (char*)malloc(10);};  
        ~temp(){free(c);};  
}temp;  

int main()  
{  
   temp a;  
   list<temp>   l1;  
   l1.push_back(a);  
   l1.clear();  
   return 0;  

}  

给出分段错误。

typedef struct temp  
{  
        int a,b;  
        char  *c;  
        temp(){ c = (char*)malloc(10);};  
        ~temp(){free(c);};  
}temp;  

int main()  
{  
   temp a;  
   list<temp>   l1;  
   l1.push_back(a);  
   l1.clear();  
   return 0;  

}  

giving segmentation fault.

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

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

发布评论

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

评论(10

故人如初 2024-07-23 11:33:37

你没有复制构造函数。

当您将“a”推入列表时,它会被复制。
因为您没有复制构造函数(为 c 分配内存并从旧 c 复制到新 c),所以 c 是 a 中的相同指针和列表中 a 的副本。

两个 a 的析构函数都被调用,第一个将成功,第二个将失败,因为 c 指向的内存已被释放。

你需要一个复制构造函数。

要查看发生了什么,请在构造函数和析构函数中添加一些计算并单步执行代码。

You don't have a copy constructor.

When you push 'a' into the list, it gets copied.
Because you don't have a copy constructor (to allocate memory for c and copy from old c to new c) c is the same pointer in a and the copy of a in the list.

The destructor for both a's gets called, the first will succeed, the second will fail because the memory c points to has already been freed.

You need a copy constructor.

To see whats happening, put some couts in the constructors and destructors and step through the code.

还如梦归 2024-07-23 11:33:37

您需要一个深复制构造函数来避免双重 free()。 您有一个临时类 (a) 变量,然后将其添加到列表中。 变量被复制。 然后清除列表,里面的元素被销毁并调用 free() 。 然后a变量被销毁,并且对同一地址再次调用free(),这会导致分段错误。

您需要一个复制构造函数来深度复制类临时变量,它将 malloc() 另一个缓冲区并复制数据。

You need a deep-copy constructor to avoid double free(). You have a variable of temp class (a), then you add it to the list. The variable is copied. Then you clear the list, the element inside is destroyed and free() is called. Then a variable is destroyed and free() is called again for the same address which leads to segmentation fault.

You need a copy constructor for deep copying class temp variables which would malloc() another buffer and copy data.

风铃鹿 2024-07-23 11:33:37

当您调用 l1.push_back(a) 时,“a”的第二个副本是复制构造的。 因此,现在有两个类相信它们拥有原始 malloc 调用中的内存,并且当删除第二个类时,它将尝试释放第一个类删除的内存。

解决方案是添加一个复制构造函数来处理类的实例实际上并不拥有数据的事实。 通常,您可以通过某种形式的引用计数来做到这一点。

At the time when you call l1.push_back(a) a second copy of 'a' is copy-constructed. As a result there are now two classes that believe they own the memory from the original malloc call, and when the second is deleted it will try to free memory deleted by the first.

The solution is to add a copy constructor that deals with the fact that instance of the class does not actually own the data. Typically you would do this by having some form of reference count.

回忆躺在深渊里 2024-07-23 11:33:37

除了给出的修复之外,您应该避免在 C++ 中使用 malloc/free。 在你的特殊情况下,我会选择一个向量:

#include <vector>

 typedef struct temp  
{  
        int a,b;  
        std::vector<char> c;  
        temp(){ c.reserve(10);};  
}temp;  

int main()  
{  
   temp a;  
   list<temp>   l1;  
   l1.push_back(a);  
   l1.clear();  
   return 0;  

}

Apart from the fixes given, you should avoid using malloc/free in C++. In your particular case, i'd go with a vector :

#include <vector>

 typedef struct temp  
{  
        int a,b;  
        std::vector<char> c;  
        temp(){ c.reserve(10);};  
}temp;  

int main()  
{  
   temp a;  
   list<temp>   l1;  
   l1.push_back(a);  
   l1.clear();  
   return 0;  

}
南…巷孤猫 2024-07-23 11:33:37

如果您不想添加复制构造函数,您可以考虑使用指向值的指针列表而不是值列表。

list<temp*>   l1;
l1.push_back( new temp() );  

但随后您必须手动删除列表中的每个对象以防止内存泄漏。

另外,结构中的 a,b 成员未初始化。 当心。

If you don't want to add copy constructor you can consider list of pointers to values instead of list of values.

list<temp*>   l1;
l1.push_back( new temp() );  

But then you have to delete manually each object in list to prevent memory leak.

Also a,b members in your struct are not initialized. Be careful.

缺⑴份安定 2024-07-23 11:33:37

除了复制构造函数之外,在这种情况下还提供 = 运算符是明智的。

struct temp {   // typedef is implicit in C++
  int a,b;
  char * c;

  // Constructor
  temp() { c = malloc(10); }
  // Destructor
  ~temp() { free(c); }
  // Copy constructor
  temp(const temp & x) { c = malloc(10); setTo(x); }
  // Operator =
  temp & operator = (const temp & x) { setTo(x); return *this; }

  // Initialize THIS to X
  void setTo(const temp & x) { a = x.a; b = x.b; memcpy(c,x.c,10); }
};

In addition to the copy constructor, it is wise to provide an = operator too in this case.

struct temp {   // typedef is implicit in C++
  int a,b;
  char * c;

  // Constructor
  temp() { c = malloc(10); }
  // Destructor
  ~temp() { free(c); }
  // Copy constructor
  temp(const temp & x) { c = malloc(10); setTo(x); }
  // Operator =
  temp & operator = (const temp & x) { setTo(x); return *this; }

  // Initialize THIS to X
  void setTo(const temp & x) { a = x.a; b = x.b; memcpy(c,x.c,10); }
};
烟─花易冷 2024-07-23 11:33:37

你需要一个复制构造函数 & 赋值运算符 - 存储在 STL 集合中的内容以副本形式存储,并且可以在向量大小更改时重新分配。

从你的代码中很难准确地看出复制构造函数的语义应该是什么,但至少分配一些内存是很简单的,这样(如果没有别的办法的话)析构函数可以释放一些东西。 如果没有更多类的详细信息,赋值运算符同样很难指定。

You need a copy constructor & an assignment operator - things stored in an STL collection are stored as copies and can be re-assigned as the vector changes size.

It's difficult to see from your code exactly what the semantics of the copy constructor should be, but at minimum it's cot to allocate some memory so that (if nothing else) the destructor has something to free. The assignment operator is equally difficult to specify without more details of your class.

毁梦 2024-07-23 11:33:37

您需要为 temp 定义一个复制构造函数。 现在,当您将 a 推入列表时,会生成 a 的副本。 副本(称为a2)通过a2.c = ac 进行初始化。 这意味着 aa2 都指向同一块内存。 当调用它们的析构函数时,该内存块被释放两次,从而导致分段错误。

鉴于您发布的内容,复制构造函数可能应该是这样的:

temp::temp (temp const &rhs)
{
    this->a = rhs.a;
    this->b = rhs.b;
    this->c = (char *) malloc (10);
    memcpy (this->c, rhs.c, 10);
}

这假设 c 指向的内容始终是 10 个字符长...

You need to define a copy constructor for temp. Right now what happens when you push a into the list is a copy of a is made. The copy (call it a2) is initialized by saying a2.c = a.c. This means both a and a2 point to the same block of memory. When their destructors are called, that block of memory is free'd twice, leading to the segmentation fault.

Given what you've posted, the copy constructor should probably be something like this:

temp::temp (temp const &rhs)
{
    this->a = rhs.a;
    this->b = rhs.b;
    this->c = (char *) malloc (10);
    memcpy (this->c, rhs.c, 10);
}

This assumes that what c points to is always 10 chars long...

悟红尘 2024-07-23 11:33:37

此代码的另一个问题是多余的分号,

temp(){ c = (char*)malloc(10);};
~temp(){free(c);};

最好将其删除:

temp(){ c = (char*)malloc(10);}
~temp(){free(c);}

Another problem with this code are extra semicolons in

temp(){ c = (char*)malloc(10);};
~temp(){free(c);};

it is better to remove them:

temp(){ c = (char*)malloc(10);}
~temp(){free(c);}
只是一片海 2024-07-23 11:33:37

多么讽刺的是,它带有“STL”标签,但缺乏 STL 才是导致问题的原因。

How ironic that this had the "STL" tag but the lack of STL is what's causing the problem.

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