拒绝手滑,我们都是稳准狠C++のmemset函数的小探究

Posted 谁吃薄荷糖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拒绝手滑,我们都是稳准狠C++のmemset函数的小探究相关的知识,希望对你有一定的参考价值。

引子

我们使用经常使用memset函数来初始化一些数据结构,常见的字符串数组、结构体、结构体数组。今天我要提出的是一个关于指针的初始化的小问题,很容易手滑写错了。
强调一下错误示例,直接用指针来memset是不对的,并不能清空指针:
void* p1 = &x;memset(p1, 0, sizeof(p1));
所以我们为了避免memset手滑导致的错误,经常会自己封装一下memset函数,如“mzero(a)”宏所示,方便大家准确地使用。

使用memset函数清空指针的demo如下:
code:

#include <iostream>
#include <cstring>

using namespace std;

//定义赋初值为0
#define mzero( a ) \\
{ \\
	memset( &a, 0x00, sizeof(a)); \\
}

int main() {
    int x=10;

    void* pNull = NULL;
    cout << "NULL ptr is:" << pNull << endl;
    cout << "x ptr is :" << &x << endl;
    cout << endl;
    
    
    void* p1 = &x;
    cout << "p1 ptr is:" << p1 << endl;

    memset(p1, 0, sizeof(p1));
    cout << "memset p : " << p1 << endl;
        
    cout << endl;
    
    void* p2 = &x;
    cout << "p2 ptr is:" << p2 << endl;
    
    memset(&p2, 0, sizeof(p2));
    cout << "memset &p ptr: " << p2 << endl;
    
    cout << endl;
    
    void* p3 = &x;
    cout << "p3 ptr is:" << p3 << endl;
    
    mzero(p3);
    cout << "mzero p: " << p3 << endl;
}

output:

NULL ptr is:0
x ptr is :0x7fff671fb2d4

p1 ptr is:0x7fff671fb2d4
memset p : 0x7fff671fb2d4

p2 ptr is:0x7fff671fb2d4
memset &p ptr: 0

p3 ptr is:0x7fff671fb2d4
mzero p: 0

正文

其实以上问题已经转化为memset初始化指针问题了。首先给出结论:
指针使用NULL赋值,值数据使用memset设为0。
虽然我们demo里memset方法和NULL方法从结果上看都初始化为0了,但是还是不建议使用memset来初始化指针。因为有些系统存在着“非零空指针”(某些 Honeywell-Bull 大型机使用比特模式 06000 作为 (内部的) 空指针),这时memset就不适用这种情况了。所以我们应该:
• 用空指针常量(或空指针)对指针变量初始化;
例如:int *p = NULL; int *p = 0;
• 用空指针常量(或空指针)对指针变量赋值;
例如:int i =222;int *p = &i;

官方文献

追根溯源,打破沙锅问到底。

memset

void * memset ( void * ptr, int value, size_t num );

Fill block of memory
Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).

Parameters

ptr:
Pointer to the block of memory to fill.

value:
Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.

num:
Number of bytes to be set to the value.
size_t is an unsigned integral type.

Return Value

ptr is returned.

旁征博引

https://www.cplusplus.com/reference/cstring/memset/
https://www.maixj.net/ict/memset-24260
http://c-faq-chn.sourceforge.net/ccfaq/node73.html

以上是关于拒绝手滑,我们都是稳准狠C++のmemset函数的小探究的主要内容,如果未能解决你的问题,请参考以下文章

在c++中怎么用memset() 给二维char型数组赋值

excel这4大逆天操作技巧,今天免费教给你,让你做表格快准狠

c++这个memset()函数有啥用? memset(啥意思,啥意思,啥意思);

使用C++的函数memset()时要注意它的操作对象是每一个字节

C++如何拒绝编译器自动生成的函数

jQuery 中的 C++ memset() 等效项