Search code examples
c++c++17memset

Unexpected behavior of memset in C++


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?


Solution

  • 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";
    }
    

    Possible output is:

    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();