views:

97

answers:

2

Hello guys, 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.

+2  A: 

Well, your Allocate function is clearly returning NULL. It's pretty difficult for us to say where and why, and it's trivial for you to set breakpoints and step through the allocator yourself, so I suggest you do that and find out where the function returns.

Peter Alexander
It returns a certain pointer...After void* p = reinterpret_cast<void*>((char*)f + sizeof(Free::SIZE_TYPE));
WhiteTopaz
+3  A: 

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

James McNellis
Thanks, I'll see if I could fix it.
WhiteTopaz
But P isn't Null when it returns, it returns 0x0042ffd8?
WhiteTopaz
Do you really need to check for null before calling placement new? I have been unable to determine this from the standard. On the one side, it seems sensible to do, on the other, calling the no throw new implies that the allocator can return 0, and the later placement construction must be skipped... I get the gut feeling that placement new *can* be called on a null pointer, but no clear reference from the standard. It could also be handled by `new (std::nothrow)` performing the check *before* calling placement new. BTW, g++4.2.1: `new (0) test;` does not call the constructor, nor dies.
David Rodríguez - dribeas
The argument to placement new must be a pointer to a memory region large enough to hold the object (and properly aligned). The null pointer does not point to such a memory region.
MSalters
@MSalters: If the allocation function returns null, a new expression performs no initialization and returns null. (§5.3.4/13)
GMan
@MSalters: §5.3.4/13: "If the allocation function returns null, initialization shall not be done, the deallocation function shall not be called, and the value of the new-expression shall be null." Since the placement operator new allocation function is effectively a no-op that returns its argument, I'm inclined to believe that it is valid...
James McNellis
@David: I think you're right; see comments above.
James McNellis
@GMan, @James McNellis: "placement new" is generically used for new epxressions that take a parameter, not just this specific form where you already have memory. I don't see a allocation function in this case, it this form of placement new also an allocation function?
MSalters
@MSalters: Placement new is typically used to refer to the ones defined in `<new>`, a "placement new expression" might be a better way of referring to placement forms of new. But what's your question? The new expression in this code presumably calls `operator(size_t, void*)`.
GMan