包含std :: vector的结构上的Malloc [英] Malloc on a struct containing a std::vector

查看:393
本文介绍了包含std :: vector的结构上的Malloc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是情况:

我使用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进行全部操作的最安全方法是什么?

解决方案

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

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

(如果您的结构是POD,即仅由基本类型和POD组成,那么这将是可以的,因为POD具有琐碎的构造函数,什么也不做.)

您面临的具体问题是结构的字符串和向量成员没有调用其构造函数,因此这些成员不存在,因此整个对象不存在.

如果要使内存管理与对象构造脱钩,可以使用放置语法:

// 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();等.)

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?

解决方案

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.)

这篇关于包含std :: vector的结构上的Malloc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆