Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 项目推送到STL容器后出现Seg故障 typedef结构温度 { INTA,b; char*c; temp(){c=(char*)malloc(10);}; ~temp(){free(c);}; }温度; int main() { 温度a; 列表l1; l1.推回(a); l1.清除(); 返回0; }_C++_Memory_Memory Management_Stl_Pointers - Fatal编程技术网

C++ 项目推送到STL容器后出现Seg故障 typedef结构温度 { INTA,b; char*c; temp(){c=(char*)malloc(10);}; ~temp(){free(c);}; }温度; int main() { 温度a; 列表l1; l1.推回(a); l1.清除(); 返回0; }

C++ 项目推送到STL容器后出现Seg故障 typedef结构温度 { INTA,b; char*c; temp(){c=(char*)malloc(10);}; ~temp(){free(c);}; }温度; int main() { 温度a; 列表l1; l1.推回(a); l1.清除(); 返回0; },c++,memory,memory-management,stl,pointers,C++,Memory,Memory Management,Stl,Pointers,给出分段错误 您没有复制构造函数 当您将“a”推入列表时,它会被复制。 因为您没有复制构造函数(为c分配内存并从旧c复制到新c),所以c是a中的同一指针,并且是列表中a的副本 两个a的析构函数都被调用,第一个将成功,第二个将失败,因为c指向的内存已经被释放 你需要一个复制构造函数 若要查看发生了什么,请在构造函数和析构函数中放入一些cout,然后逐步完成代码。您需要一个复制构造函数和赋值运算符-存储在STL集合中的内容存储为副本,并可以随着向量大小的变化而重新赋值 很难从代码中准确地看出复制构造

给出分段错误

您没有复制构造函数

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

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


你需要一个复制构造函数


若要查看发生了什么,请在构造函数和析构函数中放入一些cout,然后逐步完成代码。

您需要一个复制构造函数和赋值运算符-存储在STL集合中的内容存储为副本,并可以随着向量大小的变化而重新赋值


很难从代码中准确地看出复制构造函数的语义应该是什么,但至少需要分配一些内存,以便(如果没有其他内容)析构函数可以释放一些内容。如果没有类的更多细节,赋值运算符同样很难指定。

您需要一个深度复制构造函数来避免double free()。您有一个temp类(a)的变量,然后将其添加到列表中。变量被复制。然后清除列表,销毁其中的元素并调用free()。然后销毁一个变量,并再次为同一地址调用free(),从而导致分段错误


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

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


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

您需要为
temp
定义一个复制构造函数。现在,当您将
a
推到列表中时,会发生的是制作
a
的副本。副本(称之为
a2
)通过说出
a2.c=a.c
来初始化。这意味着
a
a2
都指向相同的内存块。当调用它们的析构函数时,该内存块被释放两次,导致分段错误

根据您所发布的内容,复制构造函数可能如下所示:

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;  

}  

这假定<代码> c>代码>指向总是10个字符长…

如果不想添加复制构造函数,可以考虑指针的值而不是值列表。
temp::temp (temp const &rhs)
{
    this->a = rhs.a;
    this->b = rhs.b;
    this->c = (char *) malloc (10);
    memcpy (this->c, rhs.c, 10);
}
列表l1;
l1.推回(新温度());
但随后您必须手动删除列表中的每个对象,以防止内存泄漏


此外,结构中的a、b成员未初始化。小心。

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

list<temp*>   l1;
l1.push_back( new temp() );  
#包括
类型定义结构温度
{  
INTA,b;
std::向量c;
temp(){c.reserve(10);};
}温度;
int main()
{  
温度a;
列表l1;
l1.推回(a);
l1.清除();
返回0;
}

在这种情况下,除了复制构造函数外,最好也提供一个=运算符

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

}

此代码的另一个问题是

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); }
};
最好将其移除:

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

多么具有讽刺意味的是,它有“STL”标签,但缺少STL才是问题的根源。

谁会投反对票让我知道原因,如果我的答案有问题,我想知道是什么。谢谢,伙计我没有-1你,但c不会被删除-删除一个对象和释放内存不是一回事。@Pete:你当然是对的,我的手指为我拨错了,谢谢:)最好在复制计算器中提到使用交换习惯用法以避免额外的内存分配。除非你有充分的理由不这样做,你应该尝试使用新的和删除的方法来代替Malc和Field.你不需要在C++中使用“TyErfFF”结构,只在C顶端提示:当你定义任何类或结构时,ESP都有指针成员,声明操作符=,拷贝构造函数是私有的。“private:temp&operator=(const-temp&);(const-temp&);”如果您对需要复制的类执行任何操作,它将不会编译,并且您知道必须提供它们。。。。要么写一个做正确事情的,比如在本例中,要么删除声明并获得默认副本,如果这些副本对所讨论的类有效的话。这是一个不幸的例子。不太了解STL的人可能会认为reserve()改变了向量的大小(实际上添加了元素),而实际上它只分配了一个缓冲区;我这样做是因为我认为他想使用push_-back命令。那是什么“缺少STL”呢?使用STL可以避免调用malloc()/free()。您也不需要任何析构函数或复制构造函数,因此可以讨论发布的大多数解决方案。
temp(){ c = (char*)malloc(10);}
~temp(){free(c);}