Search code examples
c++macosclangmemset

Why memset works wrong in apple clang compiler?


I found something strange doing problem solving with c++.
Initializing an integer array with loop works nice, but initializing it with memset function works wrong.
Below is the sample program.

#include <cstdio>
#include <limits>
#include <cstring>

using namespace std;

const int SIZE = 10;
const int INF = numeric_limits<int>::max();

int arr1[SIZE];
int arr2[SIZE];

void printArray(int *arr, int n)
{
    for(int i = 0; i < n; i++)
        printf("%-10d ", arr[i]);
}

int main()
{
    // init with loop
    for(int i = 0; i < SIZE; i++)
        arr1[i] = INF;
    printf("\nINIT WITH LOOP\n");
    printArray(arr1, SIZE);

    // init with memset
    memset(arr2, INF, sizeof(arr2));
    printf("\nINIT WITH MEMSET\n");
    printArray(arr2, SIZE);

    return 0;
}

Result :

INIT WITH LOOP
2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 
INIT WITH MEMSET
-1         -1         -1         -1         -1         -1         -1         -1         -1         -1                                 

🤔 Do I misunderstand how to use memset function? OR 🐞 Is it a bug?
For your information, my compiler version is as follows.

kimseokjin@MacBook-Air LovePS % g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Solution

  • memset converts the second operand (argument) into unsigned char and copies it into all destination bytes. In your case, this resulting unsigned char is 0xFF, which copied into all elements of type int gives their values -1.

    Documentation link: https://en.cppreference.com/w/cpp/string/byte/memset.

    Recommendation: Don't use low-level "C" functions like memset unless you are very sure of what you are doing and that you really need it. You don't need to set array values in a loop, we have algorithms in C++, such as std::fill suggested in comments. You might also want to use std::array instead of the plain "C" array.

    A more C++-like and much more readable alternative:

    std::array<int, SIZE> arr2;
    std::fill(std::begin(arr2), std::end(arr2), INF);