Search code examples
c++mallocdynamic-memory-allocationcalloc

C++ programming, dynamical memory is not working properly using malloc and calloc


I have just started learning C++ and I came on a problem I couldn't find on the Internet so I hope you can help me with.

This is my code:

int* a;
int* b;

a = (int*)calloc(1, sizeof(int));
b = (int*)calloc(5, sizeof(int));

cout << sizeof(a) << endl;
cout << sizeof(b) << endl;

What compiler returns me is: 8, 8. If I use:

cout << sizeof(*a) << endl;
cout << sizeof(*b) << endl;

Compiler returns 4, 4.

The same thing is with malloc. I am using .

What am I doing wrong? Why isn't the size of b 20 as it is 5 times bigger if int is 4 bytes long?

Thanks!


Solution

  • sizeof(*a) and sizeof(*b) are always going to be equal to 4. It seems you expect them to return the size of arrays, but you need to understand that a and b are not arrays. They are pointers to int. If sizeof(int) is 4, then sizeof(*a) is also going to be 4, and this is already known at compile time.

    With that being said, you do not need to use the C library functions malloc() and calloc() in C++. If you need manual memory allocation, use new and delete:

    a = new int;
    b = new int[5];
    

    If you need to do zero-initialization like calloc does, just use () to default-construct the allocated integers:

    a = new int();
    b = new int[5]();
    

    Instead of free(), use delete or delete[], depending on how new was called previously:

    delete a;    // Note: no '[]'
    delete[] b;  // Needs '[]'
    

    However, you do not need manual memory allocation here. Just use std::vector<int>:

    #include <vector>
    // ...
    
    std::vector<int> a(5); // 5 int elements, zero-initialized.
    std::cout << a.size() << '\n'; // Will print '5'.
    

    As a rule of thumb, your C++ code should not have any calls to new, delete, malloc(), calloc() or free(). Doing manual memory management requires more code and is error-prone. Use containers like vector and smart pointers like shared_ptr and unique_ptr instead to reduce the chance of memory and other resource leaks. These safer types are also more convenient. With vector for example, you do not have to remember the size of your allocated memory yourself. The vector keeps track of its size for you. You can also copy vectors easily by just assigning them directly. You also don't need to delete or free() vectors manually. They are automatically deleted when they go out of scope.

    As a side-note, I recommend getting rid of the habit of using endl for printing newlines. endl flushes the stream, it doesn't just print a newline. If you use it, you will be constantly flushing the output stream, which is a slow operation. You only rarely need to flush a stream, in which case you can just do so manually with << flush if the need ever arises.