Detailed explanation of c language memset

Posted by dbrown on Sun, 27 Feb 2022 17:04:54 +0100

1 function declaration

void *memset(void *s, char ch, unsigned n);

1.1 functions

Set the contents of each byte in a block of memory pointed to by s to the ASCII value specified by ch. The size of the block is specified by the third parameter. It is used to fill a given value in a memory block. It is the fastest way to clear a large structure or array.

1.2 examples

#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <memory.h>
int main(void)
{

    char buffer[] = "Hello world/n";
    printf("Buffer before memset: %s /n", buffer);

    memset(buffer, '*', strlen(buffer) );// //The array is passed directly to the first address. Mainly the modification of array pointer!! Because it can be modified, const char int and so on cannot be modified and used together with malloc
    printf("Buffer after memset: %s /n", buffer);
    return 0;
}

2 common errors

2.1 reversed the position of ch and n

Remember that if you want to clear a char a[20], it must be memset(a,0,20);
Instead of memset(a,20,0);

2.2 overuse of memset

Some programmers may have some psychological shadow and fear uninitialized memory, so they will write such code:

char buffer[20];
memset(buffer,0,sizeof(char)*20);
strcpy(buffer,"123");

memset is redundant here Because this memory will be overwritten immediately, clearing is meaningless

2.3

In fact, strictly speaking, this error cannot be regarded as the wrong memset, but it often occurs when using memset

int some_func(struct something *a){ 
 ... 
 ... 
 memset(a, 0, sizeof(a)); 
 ... 
} 

common problem:

  1. Why set memset to zero? memset(&Address,0,sizeof(Address)); We often see this usage. In fact, if it is not used, the remaining space will be set to zero when allocating data.
    Answer: 1 If it is not cleared, outliers may appear in the test. You do the following experiment to see the results
#include "iostream.h"
#include "string.h"
#include <afx.h>
int main(){
    char buf[5];
    CString str;
    CString str1;
    CString str2;
    memset(buf,0,sizeof(buf));
    for(int i = 0; i<5; i++){
        str.Format("%d",buf[i]);
        str1 +=str ;
    }
    str2.Format("%d",str1);
    cout<<str2<<endl;
    system("pause");
    return 0;
}
Design here c++Version problem

In this way, whether there is a memset or not, the output is the same
2. Actually not! Especially for the character pointer type, the remaining part is usually not 0. You might as well make an experiment to define a character array and input a string of characters. If you don't use memset to reset, there will be garbled code in the MessageBox (0 means NULL. If there is, the default character ends and the subsequent garbled code will not be output)
Q: the following demo is OK. It can set the element values in the array to character 1

#include <iostream>
#include <cstring>
using namespace std;
int main(){
    char a[5];
    memset(a,'1',5);
    for(int i = 0;i < 5;i++)
        cout<<a[i]<<" ";
    system("pause");
    return 0;
}
Output: 1 press any key to continue. . .

However, the following program is not feasible to set the element value in the array to 1

#include <iostream>
#include <cstring>
#include <windows.h>
using namespace std;
int main()
{
    int a[5];
    memset(a,1,20);//If it is changed to memset(a,1,5*sizeof(int)), it is also not allowed, because memset is assigned by bytes.
    for(int i = 0;i < 5;i++)
        cout<<a[i]<<" ";
    system("pause");
    return 0;
}
Output: 16843009 16843009 16843009 16843009 16843009 16843009 press any key to continue. . .

The question is:
1. Why can the first program and the second one not?
Because the array a of the first program is character type, the memory occupied by character type is 1Byte, and the memset function is also assigned in bytes, so you have no problem with your output. The second program a is of integer type, and the value is assigned by bytes using memset. After this assignment, the value of each array element is actually 0x01010101, that is, 16843009 in decimal system.
2. You don't want to initialize int a[5] with a for or while loop; Can you do it? (is there a function like memset() initialized)
If memset(a,1,20) is used; (in fact, the result is the same as that of memset(a,1,5*sizeof(int))) is to assign a value to the 20 bytes of memory pointed to by a, each of which is filled with characters with ASC Ⅱ as 1. After being converted to binary, 1 is 00000001, accounting for one byte. An INT element is 4 bytes, which together is 0x01010101 (hexadecimal), which is equal to 16843009, and the assignment of an INT element is completed. Therefore, it is not advisable to assign initial values to non character arrays with memset!

Assign value to bool type array:

const int N = 11;
bool arr[N];
memset(&arr, 1, sizeof(bool) * N);

Question  Why do you need it here&????????????

bool type is 1 or 0

For example, there is a structure Some x, which can be cleared as follows:

memset(&x,0,sizeof(Some));//  If X is a separate variable, use&

If it is an array of structures, Some x[10], it can be as follows:

memset(x,0,sizeof(Some)*10); X If it's an array, don't use it&,The array name is the address

memset can easily empty variables or arrays of a structure type.

For example:
	struct sample_struct
	{
	    char csName[16];
	    int iSeq;
	    int iType;
	};
For variables
	struct sample_strcut stTest;
In general, empty stTest How to:

	stTest.csName[0]={'\0'};
	stTest.iSeq=0;
	stTest.iType=0;
use memset It is very convenient:
	memset(&stTest,0,sizeof(struct sample_struct));
If array:
struct sample_struct TEST[10];
be
memset(TEST,0,sizeof(struct sample_struct)*10);
In addition:
If there is an array in the structure, you still need to initialize the array separately.

3 special examples

Some notes on copying int type arrays:

Common replication methods include:

int a[MAXN];
memset(a, 0, sizeof(a));//All elements in the array are 0
memset(a, -1, sizeof(a));//All elements in the array are - 1
memset(a, 127, sizeof(a));//All elements in the array are 2139062143 (which can be regarded as INF)

However, it should not be considered that all elements in the array after memset(a, 1, sizeof(a)) are all 1. In this way, the value of each element of the array is 16843009 (because the memset function is assigned one byte by one byte),. Each character is filled with ASC Ⅱ as 1. After it is converted to binary, 1 is 00000001, accounting for one byte. An INT element is 4 bytes, which together is 0000 00010000 00010000 00010000 00010000 0001. When converted into hexadecimal, it is 0x01010101, which is equal to 16843009

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
 
using namespace std;
#define PI acos(-1.0)
#define EPS 1e-8
const int MAXN = 410000000;
const int INF = 2100000000;
int a[MAXN];
 
int main()
{
 
    cout << a[0] << "  " << a[1] << endl;
    memset(a, -1, sizeof(a));
    cout << a[0]<< "  "  << a[1] << endl;
    memset(a, 0, sizeof(a));
    cout << a[0] << "  " << a[1] << endl;
    memset(a, 1, sizeof(a));
    cout << a[0] << "  " << a[1] << endl;
    memset(a, 2, sizeof(a));
    cout << a[0] << "  " << a[1] << endl;
    memset(a, 127, sizeof(a));
    cout << a[0] << "  " << a[1] << endl;
    return 0;
}

Output:
0  0
-1  -1
0  0
16843009  16843009
33686018  33686018
2139062143  2139062143

Reference link:
https://blog.csdn.net/leonharetd/article/details/8666384

Topics: C Back-end