#malloc&free

1 messages · Page 1 of 1 (latest)

fierce lintel
#

Hello guys, can someone help me with this exception? I've been read a lot of malloc, calloc and free and I even don't know what I concretely do wrong.

#include<stdint.h>
#include<malloc.h>
#include<vcruntime_string.h>

class ctx2
{
private:
    void* m_Buffer;
    uint32_t m_BufferLength;
    void Rebase(void* sizedBuffer, uint32_t sizedBufferSize)
    {
        uint32_t newSize = m_BufferLength + sizedBufferSize;
        void* newBuffer = malloc(newSize);

        memmove(newBuffer, m_Buffer, m_BufferLength);
        memmove((void*)((uint32_t)newBuffer + m_BufferLength), sizedBuffer, sizedBufferSize);

        free(m_Buffer); // exception is here

        m_Buffer = newBuffer;
        m_BufferLength = newSize;
    }
public:
    ctx2(void* serialized, uint32_t length)
    {
        m_Buffer = serialized;
        m_BufferLength = length;
    }
    ctx2()
    {
        m_Buffer = malloc(0);
        m_BufferLength = 0;
    }
    ~ctx2()
    {
        free(m_Buffer);
    }
    template <typename T>
    void Add(T value)
    {
        Rebase(&value, sizeof(T));
    }
    void Add(void* value, uint32_t length)
    {
        Rebase(value, length);
    }
};
int main()
{
    ctx2* ctx = new ctx2();

    ctx->Add(3);
}
zealous finchBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

naive hull
#

You probably meant to go in #1013104018739974194.

#

Or... there is new in there. Maybe not.

#

Can you clarify if you want to write C or C++?

fierce lintel
naive hull
#

Well, for C++ you forget that malloc and such even exist. Also you forget about new.

#

You use std::vector and be done with it.

#
int main()
{
    ctx2* ctx = new ctx2();

    ctx->Add(3);
}

becomes

int main()
{
    ctx2 ctx;

    ctx.Add(3);
}

No new needed.

fierce lintel
#

Problem is not in new

naive hull
#

Well, the rest of your problems disappear once you use std::vector<std::any>.

fierce lintel
fierce lintel
naive hull
#

What you're trying to do with memmove needs to instead be done with placement new.

#
    template <typename T>
    void Add(T value)
    {
        new (m_buffer) T(std::move(value));
    }

I think is the syntax.

tidal hazel
#

I mean

#

If the intent is to support stuff that isn't trivially copyable this gets stupid

#

Because you have to deal with alignment, and object lifetime as well

#

So the first memmov would have to be some combination of move and destructor calls as well

#

Plus the padding skip

#

And the second one would then be the placement new like toeger mentioned

#

If this is just for binary serialization then maybe you don't need to worry about padding and alignment but that's not really clear what and why you would do this thing for, just from the snippet

tidal hazel
#

Most of the types that can exist aren't trivially copyable

fierce lintel
tidal hazel
#

So if ctx2 is meant to be some kind of container and not just a bunch of bytes with no meaning, there's a lot you haven't dealt with

tidal hazel
#

Or a "pod"

#

Technical term being "trivially copyable" or some derivation of it

fierce lintel
tidal hazel
#

Eg you can't put a ctx2 through the Add of another ctx2

#

Also your second memmov is cursed tbh, the internal cast is definitely not the right way to cast

#

Cast your void* to a char* or std::byte* to do pointer arithmetics

#

From afar I don't see anything definitely wrong, but then again you're including non standard headers so I'm not sure the function you use have the standard behaviour or a non standard one

#

Assuming you didn't mess around with stuff, malloc 0 often yield nullptr or something that can be freed, both of which should be valid arguments for free

fierce lintel
tidal hazel
#

which is basically due to the terrible cast you tried to do and that I commented on

#

if you look at your callstack you'll almost certainly see that you're somewhere in vcruntime and not in your code, but since you cannot see the source code of vcruntime you're shown your own code, and the place in your code where you would resume execution

#

considering that you broke inside of the second memmov due to the cast, that means you're shown the line of code right after that second memmov

#

which happens to be the free

#

the tl;dr is your pointer/integer cast was absolutely a terrible idea and it immediately blew up in your face

tacit blade
#

You are casting your pointers to a 32bit unsigned integer, on a 64bit platform

cobalt lake