memset() & mistakes we do ;-)


Memset is used to fill a block of memory with a particular value.

Let's see the proper definition of memset from man page.

#include <string.h>

void *memset (void *s, int c, size_t n);

The memset function fills the first n bytes of the memory area pointed to by the s with the constant byte c.

It is a good coding practice to initialize an array and structure with 0 using memset() after declaration. 

memset for array

Eg 1 :

It's a good practice to initialize the array with 0 explicitly because it will hold junk values initially.
#include <stdio.h>

int main()
{

    char arr[64];
    printf("%s arr value %s\n",__func__, arr);
    memset(arr, 0, sizeof(arr));
    printf("%s arr value after memset %s\n",__func__, arr);
    return 0;

}

Output:
1
2
main arr value $�v� �v� ��( w�  w� �x��x��v�(�x�� ��t�w�ĉx���   �  
main arr


Eg 2 :

We can initialize an array with any value, here array is initialized with 0.

#include <stdio.h>

int main()
{

    char arr[64];
    printf("%s arr value %s\n",__func__, arr);
    memset(arr, '0', sizeof(arr));
    printf("%s arr value after memset %s\n",__func__, arr);
    return 0;

}

Output:
1
2
main arr value $�}� �}����( ~�  ~� �����}�(�� ��t�~�ĉ�.�  `�  
main arr value after memset 0000000000000000000000000000000000000000000000000000000000000000


Eg 3 :

Char array is usually initialized with " '\0' ", but it can also be initialized with "0".

char arr[20] = {'\0'};
char arr[20] = {0};

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c - ", arr[i]); //Added hyphen(-) to differentiate
    }
    printf("\n");
}

int main()
{
    int n = 10;
    char arr[10] = "Shirley";

    printArray(arr, n);
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n", arr, sizeof(arr), strlen(arr));
    // Fill whole array with 0.
    memset(arr, '\0', sizeof(arr));
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}

Output:
1
2
3
4
S - h - i - r - l - e - y -  -  -  - 
Array before memset() arr Shirley and sizeof(arr) 10 strlen(arr) 7
Array after memset()
 -  -  -  -  -  -  -  -  -  - 


Eg 4 :

Integer array is usually initialized with "\0"

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 10;
    int arr[n];

    printArray(arr, n);
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n", arr, sizeof(arr), strlen(arr));
    // Fill whole array with 0.
    memset(arr, '9', sizeof(arr));
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}

Output:
1
2
3
4
     (   q � � � 
Array before memset() arr   and sizeof(arr) 40 strlen(arr) 1
Array after memset()
9 9 9 9 9 9 9 9 9 9 


Eg 5 :

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c - ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 10;
    char arr[10] = "Shirley";

    printArray(arr, n);
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n", arr, sizeof(arr), strlen(arr));
    // Fill whole array with 0.
    memset(arr, 0, sizeof(arr));
    printf("Array after memset()\n");
    printArray(arr, n);

    return 0;
}

Output:
1
2
3
4
S - h - i - r - l - e - y -  -  -  - 
Array before memset() arr Shirley and sizeof(arr) 10 strlen(arr) 7
Array after memset()
 -  -  -  -  -  -  -  -  -  - 

In the above example, the memset was done for the whole array. Instead, we can do memset only for the indices which have the values.

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c - ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 10;
    char arr[10] = "Shirley";

    printArray(arr, n);
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n", arr, sizeof(arr), strlen(arr));
    // Fill whole array with 0.
    memset(arr, 0, strlen(arr));
    printf("Array after memset()\n");
    printArray(arr, 7);

    return 0;
}

Output:
1
2
3
4
S - h - i - r - l - e - y -  -  -  - 
Array before memset() arr Shirley and sizeof(arr) 10 strlen(arr) 7
Array after memset()
 -  -  -  -  -  -  - 

Eg 6 :

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char arr[n];
 
    sprintf(arr, "Stunning Palace");
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    printArray(arr, n);
    // Fill whole array with 0.
    memset(arr, '$', 7*sizeof(arr));
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}


Output:
1
Disallowed system call: SYS_socketcall

Array's size is just 16 bytes, so memset can't be done for more than an array size like here, "7*sizeof(arr)" is 112 (7*16).  Hence, trying to do memset beyond array's size is undefined behavior.


Eg 7:

We can fix the above problem by having the size of character instead of size of a whole array.

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c ", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char arr[n];
 
    sprintf(arr, "Stunning Palace");
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    printArray(arr, n);
    // Fill whole array with 0.
    memset(arr, '$', 7*sizeof(arr[0]));
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}


Output:
1
2
3
4
Array before memset() arr Stunning Palace and sizeof(arr) 16 strlen(arr) 15
S t u n n i n g   P a l a c e  
Array after memset()
$ $ $ $ $ $ $ g   P a l a c e  


Eg 8:

Memset can also be done from the middle of the array until a particular array size.
#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char arr[n];
 
    sprintf(arr, "Stunning Palace");
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    printArray(arr, n);
    // Fill whole array with 0.
    memset(arr+10, '$', sizeof(arr[0]));
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}


Output:
1
2
3
4
Array before memset() arr Stunning Palace and sizeof(arr) 16 strlen(arr) 15
Stunning Palace
Array after memset()
Stunning P$lace

In the above example, "Stunning Palace" became "Stunning P$lace".

Eg 9:

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char arr[n];
 
    sprintf(arr, "Stunning Palace");
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    printArray(arr, n);
    // Fill whole array with 0.
    memset(arr+5, '$', 5*sizeof(arr[0]));
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}

Output:
1
2
3
4
Array before memset() arr Stunning Palace and sizeof(arr) 16 strlen(arr) 15
Stunning Palace
Array after memset()
Stunn$$$$$alace


Eg 10 :

memset for structure


#include <stdio.h>
#include <string.h>

typedef struct student {
    char name[20];
    char roll_number[20];
}student;

int main()
{
    student st;
    printf("%s arr value student name %s and roll number %s \n",__func__, st.name, st.roll_number);
    memset(&st, 0, sizeof(st));
    printf("%s arr value after memset name %s and roll number %s \n",__func__, st.name, st.roll_number);
    return 0;
}

Output:
1
2
main arr value student name  ���� ~�(�� #��t�~�ĩ���  0�   and roll number t�~�ĩ���  0�   
main arr value after memset name  and roll number 


memset for pointer


#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<n; i++) {
        printf("%c", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char *arr = NULL;
 
    arr = (char *)malloc(n*sizeof(char));
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    memset(arr, 's', n*sizeof(arr)); 
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}

Output:
1
2
3
Array before memset() arr ����������������� and sizeof(arr) 4 strlen(arr) 17
Array after memset()
ssssssssssssssss


Here, sizeof(arr) is the size of the pointer(4/8 bytes depends on the processor), so I'm not sure how it could only memset 16 bytes, and I hope It could precisely memset 64 bytes. Hence, I wrote the below program.

#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<66; i++) {
        printf("%c", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char *arr = NULL;
 
    arr = (char *)malloc(n*sizeof(char));
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    memset(arr, 's', n*sizeof(arr)); 
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}

Output:
1
2
3
Array before memset() arr ����������������� and sizeof(arr) 4 strlen(arr) 17
Array after memset()
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss

In the above example, though printArray() iterates till 66 characters, it memsets only 64 characters. Here, we supposed to memset only 16 bytes, but we memset 64 characters since the sizeof(arr)/pointer is given. Instead of sizeof(arr), use sizeof(arr[0]) as below.


#include <stdio.h>
#include <string.h>

void printArray(char arr[], int n)
{
    int i;
    for(i=0; i<66; i++) {
        printf("%c", arr[i]);
    }
    printf("\n");
}

int main()
{
    int n = 16;
    char *arr = NULL;
 
    arr = (char *)malloc(n*sizeof(char));
    printf("Array before memset() arr %s and sizeof(arr) %d strlen(arr) %d\n",
           arr, sizeof(arr), strlen(arr));
    memset(arr, 's', n*sizeof(arr[0])); 
    printf("Array after memset()\n");
    printArray(arr, n);
    
    return 0;
}


Output:
1
2
3
Array before memset() arr ����������������� and sizeof(arr) 4 strlen(arr) 17
Array after memset()
ssssssssssssssss�y 



Comments