情况如下:
我使用 malloc 为结构分配内存。
该结构体包含各种项目,例如指针、字符串变量和向量。
事实是,当我们使用 malloc 时,没有调用任何构造函数。使用类似于以下代码的代码,我遇到过一些情况,其中某些变量起作用,而另一些则不起作用。
注意:以下代码无法编译。其目的只是为了说明情况。
struct MyStruct
{
MyClass* mFirstClass;
bool mBool;
std::string mString;
std::vector<MyClass> mVector;
};
int main()
{
MyStruct* wMyStructure;
wMyStructure = (MyStruct*) malloc (sizeof(MyStruct));
MyClass wMyClassObject;
wMyStructure->mFirstClass = new MyClass();
wMyStructure->mFirstClass->func();
wMyStructure->mBool = false;
wMyStructure->mString = "aString";
wMyStructure->mVector.push_back(wMyClassObject);
return 0;
}
通过使用指针而不是这些变量 (std::string* mString
),然后调用对象构造函数 (mString = new std::string;
),例外情况是没有抛出。
但是,我遇到过一种情况,即在没有调用构造函数的情况下使用 mString 没有问题,但当涉及到向量时,应用程序会自动退出。
这给我留下了很多问题:
-
如果没有使用构造函数,对象什么时候会抛出异常?
-
在我遇到的情况下,只有向量引起了问题。 mString 可以保留原样还是应该调用它的构造函数?
-
使用 malloc 完成整个事情最安全的方法是什么?
Here is the situation :
I use a malloc to allocate memory for a struct.
The struct contains various items such as pointers, string variables and vectors.
The fact is, when we use malloc, no constructors are called. Using a code similar to the following one, I've experienced some situation where some variables worked while others didn't.
Note : The following code doesn't compile. It's purpose is only to illustrate the situation.
struct MyStruct
{
MyClass* mFirstClass;
bool mBool;
std::string mString;
std::vector<MyClass> mVector;
};
int main()
{
MyStruct* wMyStructure;
wMyStructure = (MyStruct*) malloc (sizeof(MyStruct));
MyClass wMyClassObject;
wMyStructure->mFirstClass = new MyClass();
wMyStructure->mFirstClass->func();
wMyStructure->mBool = false;
wMyStructure->mString = "aString";
wMyStructure->mVector.push_back(wMyClassObject);
return 0;
}
By using pointers instead of those variables (std::string* mString
), followed by a call to the object constructor (mString = new std::string;
) Exception are not thrown.
However, I've experienced a situation where the mString was used without problem without the constructor being called, but when it came to the vector, the application exit automatically.
This left me with many questions:
-
When will an object throw an exception if no constructor were used?
-
In the situation I experienced, only the vector caused problem. Could mString be left as it is or should I call it's constructor?
-
What would be the safest way, using malloc, to do the whole thing?
发布评论
评论(4)
使用对象而不构造它一定是未定义的行为。任何事情都可能随时发生。如果您这样做,则不得依赖代码的任何部分来顺利运行,因为在这种情况下该语言不保证任何内容。
Using object without constructing it must be an undefined behaviour. Anything may happen at any moment. If you do this, you must not rely on any part of your code to run smoothly, because the language doesn't guarantee anything in this case.
您的代码会导致未定义的行为,因为您的
wMyStructure
没有指向对象,因此您不能在其上使用访问器运算符->
。对象仅在其构造函数完成后才开始其生命。。由于您没有调用任何构造函数,因此您没有对象。
(如果您的结构体是一个 POD,即仅由基本类型和 POD 组成,那么这就没问题,因为 POD 具有简单的构造函数,它们不执行任何操作。)
您面临的具体问题是您的字符串和向量成员struct 无法调用它们的构造函数,因此这些成员不存在,因此整个对象也不存在。
如果要将内存管理与对象构造分离,可以使用放置语法:(
完成后,您必须手动销毁这些对象,
px->~MyClass();
等和他们在一起。)Your code causes undefined behaviour, because your
wMyStructure
does not point to an object, so you may not use the accessor operator->
on it.An object only commences its life after its constructor has completed. Since you don't call any constructor, you do not have an object.
(If your struct were a POD, i.e. just consisting of primitive types and PODs, then this would be OK, because PODs have trivial constructors, which do nothing.)
The concrete problem you're facing is that the string and vector members of your struct didn't get to call their constructors, so those members don't exists, and hence the entire object doesn't.
If you want to decouple memory management from object construction, you can use placement syntax:
(You have to destroy those objects manually,
px->~MyClass();
etc., when you're done with them.)如果不调用构造函数,则没有对象。您刚刚分配了一些空间。
这都是未定义的行为,几乎任何事情都可能发生。没有规则。
最安全的方法是不使用malloc,而是使用将调用构造函数的
new
进行分配。就这么简单If you don't call the constructor, there is no object. You have just allocated some space.
This is all undefined behavior, just about anything could happen. There are no rules.
The safest way would be not to use malloc, but allocate using
new
that will call constructors. It is as simple as this使用未初始化的对象是未定义的行为。异常可能随时抛出,或者根本不抛出。
It is undefined behaviour to use a non-initialized object. Exception may be thrown at any time- or not at all.