Reputation: 479
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
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
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
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