Amaterastis
Amaterastis

Reputation: 479

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!

Upvotes: 1

Views: 547

Answers (3)

Luis Colorado
Luis Colorado

Reputation: 12698

sizeof(a) is the size of the pointer (this is 8 in a 64bit architecture normally), while sizeof(*a) is the size of the pointed to element (an integer value). Nothing returned by sizeof operator has dynamic nature (as the number of elements returned by calloc(3))

By the way, calloc() is strongly deprecated in C++. Its use is reserved to cases in which you have to pass the pointers to C code and for legacy code. Use the operators new and new [] (the last one in this case). But none of these will change things, the sizeof operator will continue returning the values you got. If you want to check the size of the returned array, then check the parameters passed to both operators.

Upvotes: 0

user6409506
user6409506

Reputation:

You are taking the sizeof a pointer in the first case and the size of the element int the second. *a is for your intents and purposes the same as a[0]. The size of the pointer is architecture dependent, and the size of the int is 4.

The sizeof value is evaluated at compile time. Dynamic memory allocation occurs at runtime. To find out the amount allocated at run time you can look at overloading the new operator (not recommended) or using the containers as the comments have suggested.

Upvotes: 0

Nikos C.
Nikos C.

Reputation: 51890

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.

Upvotes: 3

Related Questions