Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does placement new call the constructor if the passed pointer is null?

I tried to converted a vc7.1 project to vs2010 which I got from codeproject.(And here's the link h tt p://www.codeproject.com/KB/cpp/transactions.aspx?fid=11253&df=90&mpp=50&noise=3&sort=Position&view=Expanded&fr=1#xx0xx

But after converted and modified its configuration.

I find it debug unsuccessfully, it says Unhandled exception at 0x0028e7b9 in DrawIt.exe: 0xC0000005: Access violation writing location 0x00000000.

The error line goes like this

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

And the function

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;
}

Anyone got idea, plz?

Since I'm not good at C++, it'll take some time before I figure out how to solve this problem. Just uploaded the source codesource file, it would be appreciated if someone could help.

like image 419
WhiteTopaz Avatar asked Oct 27 '10 07:10

WhiteTopaz


1 Answers

[This answer may be wrong; see the comments for discussion; I'll leave this undeleted for the moment so we can figure out what the answer is]

Allocate returns NULL in several failure cases.

You don't check the result of calling Allocate before you use it.

You need to check the result. Alternatively, you can throw an exception when you have a failure.

like image 75
2 revs Avatar answered Sep 23 '22 15:09

2 revs