当前位置:网站首页>Detailed explanation of C language memset

Detailed explanation of C language memset

2022-06-12 14:18:00 zou_ albert

1 Function declaration

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

1.1 function

take s The contents of each byte in the memory pointed to are all set to ch designated ASCII value . The size of the block is specified by a third parameter , The function is to fill a given value in a block of memory , It is the fastest way to clear a large structure or array .

1.2 Example

#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 Wait until these cannot be modified   and malloc  Matching use of 
    printf("Buffer after memset: %s /n", buffer);
    return 0;
}

 Insert picture description here

2 Common mistakes

2.1 It's reversed ch and n The location of .

Be sure to remember that if you want to put one char a[20] Zero clearing , It must be memset(a,0,20);
instead of memset(a,20,0);

2.2 overuse memset

Some programmers may have some kind of psychological shadow , Fear of uninitialized memory , So they write code like this :

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

there memset It's redundant . Because this memory will be overwritten immediately , There is no point in clearing .

2.3

In fact, strictly speaking, this mistake cannot be regarded as a mistake memset, But it is often used memset Where

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

common problem :

  1. Why use memset Zeroing ?memset(&Address,0,sizeof(Address)); We often see such usage , If you don't use it , When allocating data , The remaining space will also be set to zero .
    answer : 1. If not empty , There may be outliers 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;
}
 Here we design c++ Version problem 

Write it like this , Is there any memset, The output is the same
2. It's not ! Especially for character pointer type , The rest is usually not for 0 Of , We might as well make an experiment , Defines an array of characters , And enter a string of characters , If not memset Realize zero clearing , send MessageBox There will be garbled code when it is displayed (0 Express NULL, If there is , End with the default character , Will not output the following garbled code )
ask : as follows demo Yes. , Can set the element values in the array to characters 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 1 1 1 1  Please press any key to continue . . .

however , The following program wants to set the element value in the array to 1, But it is not feasible

#include <iostream>
#include <cstring>
#include <windows.h>
using namespace std;
int main()
{
    
    int a[5];
    memset(a,1,20);// If this is changed to memset(a,1,5*sizeof(int)) You can't either , because memset Assign values by byte .
    for(int i = 0;i < 5;i++)
        cout<<a[i]<<" ";
    system("pause");
    return 0;
}
 Output :16843009 16843009 16843009 16843009 16843009  Please press any key to continue . . .

The problem is :
1, Why can the first program , And the second one can't ?
Because the array of the first program a It's character type , The memory size occupied by character type is 1Byte, and memset Functions are also assigned in bytes , So there is no problem with your output . And the second program a It's integral , Use memset Or by byte , After this assignment , The value of each array element is actually 0x01010101 It's decimal 16843009.
2, I don't want to use it for, or while Loop to initialize int a[5]; Can you do that? ?( Is there one like memset() Such function initialization )
If you use memset(a,1,20);( Actually with memset(a,1,5*sizeof(int)) The result is the same ) That's right a Point to the memory of 20 To assign a value in bytes , Every one of them ASCⅡ by 1 To fill in , When it's binary ,1 Namely 00000001, Take up a byte . One INT The element is 4 byte , Together, it's 0x01010101( Hexadecimal ), Is equal to 16843009, It's done with a INT The assignment of the element . So use memset It is not advisable to assign initial values to non character arrays !

Yes bool Type array assignment :

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

Question   Why do we need &????????????

bool The type is 1 or 0.

For example, there is a structure Some x, It can be cleared like this :

memset(&x,0,sizeof(Some));//  X If it is a single variable, you need to use &

If it's an array of structs Some x[10], It can be like this :

memset(x,0,sizeof(Some)*10); X Do not use arrays &, The array name is the address 

memset You can easily empty a variable or array of structure type .

 Such as :
	struct sample_struct
	{
    
	    char csName[16];
	    int iSeq;
	    int iType;
	};
 For variables 
	struct sample_strcut stTest;
 In general , Empty stTest Methods :

	stTest.csName[0]={
    '\0'};
	stTest.iSeq=0;
	stTest.iType=0;
 use memset It's very convenient :
	memset(&stTest,0,sizeof(struct sample_struct));
 If it's an 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

to int Several points for attention when copying an array of type :

Commonly used 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( Think of it as INF)

But we must not think that memset(a, 1, sizeof(a)) All the elements in the last array are 1 了 , The value of each element of such an array is : 16843009( because memset The function is assigned by byte ),. Every one of them ASCⅡ by 1 To fill in , When it's binary ,1 Namely 00000001, Take up a byte . One INT The element is 4 byte , Together is 0000 0001,0000 0001,0000 0001,0000 0001, Into hexadecimal is 0x01010101, 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

原网站

版权声明
本文为[zou_ albert]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010513031536.html