对包含 std::vector 的结构进行 Malloc

发布于 2024-11-29 22:58:35 字数 1115 浏览 0 评论 0 原文

情况如下:

我使用 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 没有问题,但当涉及到向量时,应用程序会自动退出。

这给我留下了很多问题:

  1. 如果没有使用构造函数,对象什么时候会抛出异常?

  2. 在我遇到的情况下,只有向量引起了问题。 mString 可以保留原样还是应该调用它的构造函数?

  3. 使用 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:

  1. When will an object throw an exception if no constructor were used?

  2. In the situation I experienced, only the vector caused problem. Could mString be left as it is or should I call it's constructor?

  3. What would be the safest way, using malloc, to do the whole thing?

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

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

发布评论

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

评论(4

伤感在游骋 2024-12-06 22:58:35

使用对象而不构造它一定是未定义的行为。任何事情都可能随时发生。如果您这样做,则不得依赖代码的任何部分来顺利运行,因为在这种情况下该语言不保证任何内容。

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.

小瓶盖 2024-12-06 22:58:35

您的代码会导致未定义的行为,因为您的 wMyStructure 没有指向对象,因此您不能在其上使用访问器运算符 ->

对象仅在其构造函数完成后才开始其生命。。由于您没有调用任何构造函数,因此您没有对象。

(如果您的结构体是一个 POD,即仅由基本类型和 POD 组成,那么这就没问题,因为 POD 具有简单的构造函数,它们不执行任何操作。)

您面临的具体问题是您的字符串和向量成员struct 无法调用它们的构造函数,因此这些成员不存在,因此整个对象也不存在。

如果要将内存管理与对象构造分离,可以使用放置语法:(

// get some memory
char arena[HUGE_VAL];
void * morespace = malloc(HUGE_VAL);

// construct some objects
MyClass   * px = new (arena + 2000) MyClass;  // default constructor
YourClass * py = new (morespace + 5000) YourClass(1, -.5, 'x');  // non-default constructor

完成后,您必须手动销毁这些对象,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:

// get some memory
char arena[HUGE_VAL];
void * morespace = malloc(HUGE_VAL);

// construct some objects
MyClass   * px = new (arena + 2000) MyClass;  // default constructor
YourClass * py = new (morespace + 5000) YourClass(1, -.5, 'x');  // non-default constructor

(You have to destroy those objects manually, px->~MyClass(); etc., when you're done with them.)

人间☆小暴躁 2024-12-06 22:58:35

1) 如果没有使用构造函数,对象什么时候会抛出异常?

如果不调用构造函数,则没有对象。您刚刚分配了一些空间。

2)在我遇到的情况下,只有向量引起了问题。 mString 可以保留原样还是我应该调用它的构造函数?

这都是未定义的行为,几乎任何事情都可能发生。没有规则。

3)使用 malloc 来完成整个事情最安全的方法是什么?

最安全的方法是使用malloc,而是使用将调用构造函数的new进行分配。就这么简单

MyStruct* wMyStructure = new MyStruct;

1 ) When will an object throw an exception if no constructor were used ?

If you don't call the constructor, there is no object. You have just allocated some space.

2 ) In the situation I experienced, only the vector caused problem. Could mString be left as it is or should I call it's constructor ?

This is all undefined behavior, just about anything could happen. There are no rules.

3 ) What would be the safest way, using malloc, to do the whole thing ?

The safest way would be not to use malloc, but allocate using new that will call constructors. It is as simple as this

MyStruct* wMyStructure = new MyStruct;
稍尽春風 2024-12-06 22:58:35

使用未初始化的对象是未定义的行为。异常可能随时抛出,或者根本不抛出。

It is undefined behaviour to use a non-initialized object. Exception may be thrown at any time- or not at all.

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