C++ 如何手动初始化std::list';C++;?如果类的指针有成员列表,该怎么办<>;,不能用新的吗?

C++ 如何手动初始化std::list';C++;?如果类的指针有成员列表,该怎么办<>;,不能用新的吗?,c++,constructor,std,stdvector,stdlist,C++,Constructor,Std,Stdvector,Stdlist,假设这是c中的一个结构/类++ struct MyClass{ list<int> ls; }; 那么std::list中是否有任何函数可用于解决此问题? 我试着用std::vector做同样的事情,因为当我使用calloc()时没有问题 struct MyClass{ 向量ls; }; MyClass*指针=calloc(1,sizeof(MyClass))//使用calloc 指针->ls.向后推(123);//一切都好 但在使用malloc执行此操作时:- struct

假设这是c中的一个结构/类++

struct MyClass{
  list<int> ls;
};
那么std::list中是否有任何函数可用于解决此问题?

我试着用std::vector做同样的事情,因为当我使用calloc()时没有问题

struct MyClass{
向量ls;
};
MyClass*指针=calloc(1,sizeof(MyClass))//使用calloc
指针->ls.向后推(123);//一切都好
但在使用malloc执行此操作时:-

struct MyClass{
  vector<int> ls;
};
MyClass *pointer = malloc(1, sizeof(MyClass));//using malloc
pointer->ls.push_back(123); // Core dump :-(
struct MyClass{
向量ls;
};
MyClass*指针=malloc(1,sizeof(MyClass))//使用malloc
指针->ls.向后推(123);//堆芯转储:-(

C++区分内存和内存中的对象。您正在使用
malloc
calloc
分配内存,但您没有在分配的内存中创建任何对象

您可以使用placement new表达式在分配的存储中手动创建对象:

new(pointer) MyClass /*initializer*/;
这将在
指针
指向的存储位置创建一个新的
MyClass
对象。
/*初始值设定项*/
是该对象的可选初始值设定项,其含义与变量声明中的含义相同

MyClass my_class /*initializer*/;
您可能需要
#include
来使用我在上面使用的placement新表单,并且您需要确保分配的内存块足够大,并且足够对齐
MyClass
对象类型

即使在存储位置未创建任何对象,但如果指针指向某个对象,也会导致未定义的行为,您正在观察到。请注意,从技术上讲,这对于任何(甚至是基本的)类型都是正确的。这可能会在将来发生变化,以允许至少使用普通类型(或某些类似类别)要在使用时隐式创建,但对于标准容器之类的非平凡类类型,这肯定不会改变


<>也注意到<代码> MalcC < /C>和<代码> CaloC返回“代码>空格*<代码> >,C++中不能隐式地将其转换为不同的指针类型。
MyClass *pointer = static_cast<MyClass*>(malloc(sizeof(MyClass)));

你也应该避免使用<代码> Malc C < /C>和<代码> CaloC等。C++有自己的内存分配函数,称为(混淆)<代码>运算符new < /C> >,它使用类似MalOC/(将内存初始化为零(如

calloc
不起作用,因为新位置中的初始值设定项可以和/或将执行此操作):

免费
模拟为:

operator delete(pointer);
它仍然只分配内存,而不像新的位置那样创建对象


非placement new表达式
new MyClass;
分配内存(通过调用
operator new
)并创建一个对象,就像通过上述placement new表单一样


不过,您不必为所有这些烦恼,因为如果需要,您可以使用智能指针并在以后对其进行初始化:

std::unique_ptr<MyClass> ptr; // No memory allocated or object created

ptr = std::make_unique<MyClass>(/*constructor arguments*/); // Allocates memory and creates object

// Object is automatically destroyed and memory freed once no `std::unique_ptr` references the object anymore.
std::unique\u ptr ptr;//未分配内存或创建对象
ptr=std::make_unique(/*构造函数参数*/);//分配内存并创建对象
//一旦不再有'std::unique_ptr'引用对象,对象将自动销毁并释放内存。

首先,您不应使用从
new
malloc
等返回的原始指针作为拥有指针。
std::unique_ptr
默认具有正确的所有权语义,并且不需要您执行任何进一步的操作。

C++区分内存和该内存中的对象。您正在为ith
malloc
calloc
,但您没有在分配的内存中创建任何对象

您可以使用placement new表达式在分配的存储中手动创建对象:

new(pointer) MyClass /*initializer*/;
这将在
指针
指向的存储位置创建一个新的
MyClass
对象。
/*初始值设定项*/
是该对象的可选初始值设定项,其含义与变量声明中的含义相同

MyClass my_class /*initializer*/;
您可能需要
#include
来使用我在上面使用的placement新表单,并且您需要确保分配的内存块足够大,并且足够对齐
MyClass
对象类型

即使在存储位置未创建任何对象,但如果指针指向某个对象,也会导致未定义的行为,您正在观察到。请注意,从技术上讲,这对于任何(甚至是基本的)类型都是正确的。这可能会在将来发生变化,以允许至少使用普通类型(或某些类似类别)要在使用时隐式创建,但对于标准容器之类的非平凡类类型,这肯定不会改变


<>也注意到<代码> MalcC < /C>和<代码> CaloC返回“代码>空格*<代码> >,C++中不能隐式地将其转换为不同的指针类型。
MyClass *pointer = static_cast<MyClass*>(malloc(sizeof(MyClass)));

你也应该避免使用<代码> Malc C < /C>和<代码> CaloC等。C++有自己的内存分配函数,称为(混淆)<代码>运算符new < /C> >,它使用类似MalOC/(将内存初始化为零(如

calloc
不起作用,因为新位置中的初始值设定项可以和/或将执行此操作):

免费
模拟为:

operator delete(pointer);
它仍然只分配内存,而不像新的位置那样创建对象


非placement new表达式
new MyClass;
分配内存(通过调用
operator new
)并创建一个对象,就像通过上述placement new表单一样


不过,您不必为所有这些烦恼,因为如果需要,您可以使用智能指针并在以后对其进行初始化:

std::unique_ptr<MyClass> ptr; // No memory allocated or object created

ptr = std::make_unique<MyClass>(/*constructor arguments*/); // Allocates memory and creates object

// Object is automatically destroyed and memory freed once no `std::unique_ptr` references the object anymore.
std::unique\u ptr ptr;//未分配内存或创建对象
ptr=std::make_unique(/*构造函数参数*/);//分配内存并创建对象