在malloc()之后在结构中初始化ref-to-ptr

时间:2014-11-04 23:19:57

标签: c++ c visual-studio-2012 struct msvcrt

我正在使用VC ++和Debug CRT在开发中使用DLL时遇到问题。

我有一个这样的结构,拿着一些参考文献。

struct DATA
{
    TA*& a;
    TB*& b;
    TC*& c;
    TD*& d;

    char** chars;
    int num_chars;

private:
    // because:
    // DATA a;
    // DATA b;
    // a = b; // is impossible
    DATA& operator=(const DATA&); // append " = delete;" for C++11

    // Default ctor (private because struct should be manually constructed using malloc)
    DATA(TA*& a, TB*& b, TC*& c, TD*& d)
        : a(a),
          b(b),
          c(c),
          d(d),
          chars(NULL),
          num_chars(0)
    {}
};

并构建它:

DATA*& Get()
{
    static struct DATA *data = (struct DATA*)malloc(sizeof(struct DATA));
    return data;
}

现在它应该保留未初始化的ref-to-ptrs,我想通过以下方式:

void func(TA* a, TB* b, TC* c, TD* d)
{
    Get()->a = a;
    Get()->b = b;
    Get()->c = c;
    Get()->d = d;
    ...
}

适用于所有事情,但是参考ptrs ..

当我使用WinDbg(在远程内核调试&#34; kd&#34;实例中)INVALID_POINTER_WRITE_FILL_PATTERN_cdcdcdcd时,我在第一个Get()->a = a;上获得!analyze -v -f < / p>

感谢您的帮助! :)

编辑:解决方案

解决方案是使用正确答案中的点。

让c&#39;公开是必要的:

struct DATA
{
    TA*& a;
    TB*& b;
    TC*& c;
    TD*& d;

    char** chars;
    int num_chars;

    // Default ctor
    DATA(TA*& a, TB*& b, TC*& c, TD*& d)
        : a(a),
          b(b),
          c(c),
          d(d),
          chars(NULL),
          num_chars(0)
    {}

private:
    // because:
    // DATA a;
    // DATA b;
    // a = b; // is impossible
    DATA& operator=(const DATA&); // append " = delete;" for C++11
};

然后使用placement new构造结构:

DATA*& Get(...)
{
    // ... some stuff, overloading, other init-method etc. to init and construct like:
    static struct DATA *data = 
        new(malloc(sizeof(struct DATA))) DATA(...); // At least assign ALL references in the c'tor
    return data;
}

然后使用它并且可能指定所有没有参考的内容:

void func(TA* a, TB* b, TC* c, TD* d)
{
    Get(a, b, c, d);

    Get()->chars = ...
    ...
}

免费提供整件事需要通过调用d&tor; free来明确完成,因为我们使用placement new

data->~DATA();
free(data);

2 个答案:

答案 0 :(得分:2)

如果没有初始化引用,则无法声明引用。您的struct具有默认构造函数,因为您显式声明了非默认构造函数。仅分配malloc不足以创建有效的DATA对象,因为它是non-POD type

继续尝试声明一个真正的默认构造函数(即DATA() {}),你会发现由于引用成员,这不起作用。如果您想使用malloc分配非POD对象,则必须使用placement new

答案 1 :(得分:1)

请注意malloc()会返回未初始化的内存。需要构造C ++对象。将对象放入未初始化内存的方法是使用placement new(此代码还添加了清理):

#include <new>
DATA*& Get()
{
    static DATA *data = new(malloc(sizeof(struct DATA))) DATA(...);
    static std::unique_ptr<DATA, void(*)(DATA*)> clean(data,
                                                [](DATA* d){
                                                    d->~DATA();
                                                    free(data);
                                                });

    return data;
}

C ++中没有办法重新引用引用,即它们需要在构造期间设置。就个人而言,我不会使用malloc(),而是使用合适的分配:

    static DATA* data(new DATA(...));

...或者,正如Jarod42指出的那样,实际上

    static DATA data(...);
    return &data;