I have noticed unexpected behavior of memset()
when used with dynamic arrays.
// This works well, sets value of each index = 0
int dp[5];
memset(dp, 0, sizeof(dp));
// This one doesn't work as expected, there are garbage values at some indexes
int *dp = new int[5];
memset(dp, 0, sizeof(dp));
// And this one works as expected
int *dp = new int[5];
memset(dp, 0, sizeof(dp[0]) * n);
What defines the reason for this unexpected behavior?
EDIT:
I understand that sizeof(dp)
gives the size of pointer where as sizeof(dp[0])
gives the size of dp[0]
. My main concern is if first one is working fine with the pointer size i.e. sizeof(dp)
then why isn't the second one working similarly, why are there garbage values?
This
int dp[5];
declares dp
as an array of 5 integers, a int[5]
. Here dp
is not a pointer. It is an array. Arrays are not pointers. The sizeof dp
is 5 * sizeof int
.
On the other hand, this:
int* dp = ... whatever ...;
declares dp
as a pointer to int
, a int*
. The sizeof dp
is that of a int*
.
Important: Pointers are not arrays and arrays are not pointers. The dp
here is very different to the dp
above. Here dp
is a pointer to a single int
, the first element of the dynamically allocated array.
When dp
is a pointer, then dp[0]
is equivalent to *(dp + 0)
, hence 5 * sizeof dp[0]
is the total size of the array when dp
points to the first element of an array with 5
integers.
Consider this:
#include <iostream>
int main() {
std::cout << sizeof(int) << "\n";
std::cout << sizeof(int*) << "\n";
std::cout << sizeof(int[5]) << "\n";
}
4
8
20
Here the size of a integer is 4 while the size of a pointer to integer is 8. Those numbers can differ, but the size of an array of 5 integers is always 5 * sizeof(int)
and typically sizeof(int*)
is much smaller than sizeof(int[5])
.
About your edit...
My main concern is if first one is working fine with the pointer size i.e. sizeof(dp) then why isn't the second one working similarly, why are there garbage values?
See above. In the first example dp
is not a pointer. When you declare dp
as int dp[5];
then dp
is not a pointer. It is an array. Arrays are not pointers. int* dp = ...
on the other hand declares dp
as a pointer to integer.
PS: Use a vector instead of manually managed c-arrays and skip the usage of memset
:
std::vector<int> x(5);
std::cout << "number of elements: " << x.size();