【问题标题】:Does placement new call the constructor if the passed pointer is null?如果传递的指针为空,placement new 是否会调用构造函数?
【发布时间】:2011-05-01 04:00:36
【问题描述】:

我试图将一个 vc7.1 项目转换为我从 codeproject 获得的 vs2010。(这里是链接 h tt p://www.codeproject.com/KB/cpp/transactions.aspx?fid=11253&df=90&mpp =50&noise=3&sort=位置&view=展开&fr=1#xx0xx

但是经过转换和修改后的配置。

我发现它调试不成功,它说在 DrawIt.exe 中的 0x0028e7b9 处出现未处理异常:0xC0000005:访问冲突写入位置 0x00000000。

错误行是这样的

data = new(Mm::Allocate(sizeof(DocData), sid)) DocData();

还有功能

void* Allocate(size_t size, SPACEID sid)
{
    AUDIT

    Spaces::iterator s = spaces.find(sid);
    if (s == spaces.end())
        return NULL;

    Space& space = s->second;
    if (!space.transacting) 
        return NULL;

    size = max(size, sizeof(Free));

    // TODO: assert that "data" is allocated in space
    space.AssertData();

    // are there any more free chunks?
    if (!space.data->sFreeHead) {
        space.data->Insert(space.More(size));
    }

    AUDIT

    // find the first chunk at least the size requested
    Free* prev = 0;
    Free* f = space.data->sFreeHead;
    while (f && (f->size < size)) {
        prev = f;
        f = f->next;
    }

    AUDIT
    // if we found one, disconnect it
    if (f) {
        space.data->locTree.remove((size_t)f);

        if (prev) prev->next = f->next;
        else space.data->sFreeHead = f->next;

        f->next = 0;
        memset(&f->loc, 0, sizeof(f->loc));
    } else {
        f = space.More(size);
    }

    // f is disconnected from the free list at this point

    AUDIT

    // if the free chunk is too(?) big, carve a peice off and return
    // the rest to the free list
    if (f->size > (2*(size + sizeof(Free)))) {
        Free* tmp = space.data->Slice(f, size); // slice size byte off 'f'
        space.data->Insert(f); // return the remainder to the free list
        f = tmp;
    }

    AUDIT

    CHECK_POINTER(f)

    void* p = reinterpret_cast<void*>((char*)f + sizeof(Free::SIZE_TYPE));

    CHECK_POINTER(p)

    return p;
}

请问有人知道了吗?

由于我不擅长 C++,因此需要一些时间才能弄清楚如何解决这个问题。 刚刚上传了源代码source file,如果有人可以帮忙,将不胜感激。

【问题讨论】:

  • 这是一个非常好的问题,可以用更短的术语重申:如果传递的指针为空,placement new 是否调用构造函数?

标签: c++ visual-studio-2010 mfc stl atl


【解决方案1】:

[这个答案可能是错误的;参见 cmets 进行讨论;我暂时不要删除它,这样我们就可以弄清楚答案是什么]

Allocate 在几种失败情况下返回NULL

调用Allocate之前,你没有检查结果。

您需要检查结果。或者,您可以在失败时抛出异常。

【讨论】:

  • 谢谢,我看看能不能解决。
  • 但是P返回时不是Null,而是返回0x0042ffd8?
  • placement new 的参数必须是一个指向足够大以容纳对象(并正确对齐)的内存区域的指针。空指针不指向这样的内存区域。
  • @MSalters: §5.3.4/13: "如果分配函数返回 null,则不应进行初始化,不应调用释放函数,并且 new-expression 的值应为空值。”由于放置运算符 new 分配函数实际上是一个返回其参数的空操作,我倾向于相信它是有效的......
  • @GMan,@James McNellis:“placement new”通常用于带有参数的新表达式,而不仅仅是您已经有记忆的这种特定形式。在这种情况下我没有看到分配函数,这种新的放置形式也是分配函数吗?
【解决方案2】:

好吧,您的 Allocate 函数显然返回了 NULL。我们很难说在哪里和为什么,而且你自己设置断点和单步执行分配器对你来说是微不足道的,所以我建议你这样做并找出函数返回的位置。

【讨论】:

  • 返回某个指针...在void* p = reinterpret_cast((char*)f + sizeof(Free::SIZE_TYPE));
猜你喜欢
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 2014-06-15
  • 2014-08-07
  • 2010-10-31
  • 2010-09-26
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多