Search code examples
cmemorymemory-managementheap-memorylow-level

Is there any difference on allocating memory like this?


I think i have a beginner doubt. I don't know if it is a very stupid question, but there is any difference between this two cases:

Generic struct:

typedef struct {

    void* data;

} Object;

1st case: This case allocates memory on a pointer and then, the pointer is returned.

Object* NewObject1(const void* data) {

    Object* This = (Object*)malloc(sizeof(Object));
    memcpy_s(&This->data, sizeof(void**), &data, sizeof(void**));

    return This;
}

2nd case: In this case, the memory is allocated on a pointer that was given by the user.

void NewObject2(Object** This, const void* data) {

    *This = (Object*)malloc(sizeof(Object));
    memcpy_s(&(*This)->data, sizeof(void**), &data, sizeof(void**));

}

The result, actually, is the same:

int main(){

    Object* a = NewObject1((void*)10);
    printf("a->data = %d\n", (int)a->data);

    Object* b = NULL;
    NewObject2(&b, (void*)10);
    printf("b->data = %d\n", (int)b->data);

    return 0;
}

Output:

a->data = 10
b->data = 10

So my question is: There is any real difference between allocating memory as in the first case or as in the second. For example, memory safety, performance, etc.


Solution

  • The two methods of returning a value the same. You can either return by value, or use a pointer argument that points to where the "returned" value should be written.

    However there are several other strange things with your code:

    • Instead of memcpy_s, you should just write This->data = data; and (*This)->data = data; respectively. And fix the const-correctness.
    • (void *)10 is probably not a valid address, this might cause a trap, bus error or other problem. (undefined behaviour if it is not the address of an actual object)
    • Casting the result of malloc is redundant or worse.
    • The return value of malloc should be checked.