【C言語】memset()第3引数で sizeof(ポインタ変数名)は
多分バグ

誤り? memset(ptr,0,sizeof(ptr)) 指す先のサイズ! memset(ptr,0,sizeof(*ptr))

warning: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination;

警告: ‘sizeof(ポインタ)’はポインタのサイズで指す先のサイズではない
[-Wsizeof-pointer-memaccess]

■memset(ptr,0,sizeof(ptr))は多分バグ

#include    <stdio.h>
#include    <string.h>
typedef struct {
    char body[1024] ;
} tag_t ;
int main(void) {
    tag_t   x;
    tag_t   *pointer = &x;
    
    //★ダメ:ポインタのサイズでクリア?
    memset(pointer,0,sizeof(pointer));
}

上記のsizeof(pointer)は
ポインタのサイズなので
4byte(ILP32bitコンパイラの場合)か
8byte(LP64bitコンパイラの場合)
にしかなりません。

文脈からプログラマが欲しいのは
ポインタのサイズではなくて
ポインタの指す先のサイズと思われます。

●非推奨修正案 sizeof(型)

#include    <stdio.h>
#include    <string.h>
typedef struct tag {
    char body[1024] ;
} tag_t ;
int main(void) {
    tag_t   x;
    tag_t   *pointer = &x;
    
    //非推奨
    memset(pointer,0,sizeof(struct tag));
}

memset(pointer,0,sizeof(struct tag))と
書いてしまうと
意図した動きはしますが、
このmemset()の1行だけから
pointerとstruct tag の関係が
読者にわかりません。

●推奨修正案 sizeof(*pointer)

#include    <stdio.h>
#include    <string.h>
typedef struct {
    char body[1024] ;
} tag_t ;
int main(void) {
    tag_t   x;
    tag_t   *pointer = &x;
    
    //ポインタが指す先のサイズでクリア
    memset(pointer,0,sizeof(*pointer));
}

ポインタの指す先のサイズが欲しい場合は
sizeof( pointer)ではなくて
sizeof(*pointer)とします。


■memset(&ptr,0,sizeof(ptr))はptr = NULL?

#include    <stdio.h>
#include    <string.h>
typedef struct {
    char body[1024] ;
} tag_t ;
int main(void) {
    //変数宣言
    tag_t   variableX;
    tag_t   variableY;
    tag_t   variableZ;
    tag_t   *pointer ;
    
    //変数初期化
    memset(&variableX,  0,sizeof(variableX));
    memset(&variableY,  0,sizeof(variableY));
    memset(&variableZ,  0,sizeof(variableZ));
    memset(&pointer,    0,sizeof(pointer));//pointer=NULL?
}

memsetを使って
ポインタ変数 pointer を0で初期化すると
ポインタ変数 pointer が
NULLポインタになる保証がありません。

参考:

C-FAQ 5.17

現実にNULLポインターの内部表現が「0番地」では無いものも存在する。

●修正案 ptr = NULL

#include    <stdio.h>
#include    <string.h>
typedef struct {
    char body[1024] ;
} tag_t ;
int main(void) {
    tag_t   variableX ={0};
    tag_t   variableY ={0};
    tag_t   variableZ ={0};
    tag_t   *pointer  = NULL ;
}

ポインタ自身の初期化は単純に NULL を代入して下さい。


■malloc(sizeof(ptr))は*が無い?

(warning) Size of pointer ‘ptr’ used instead of size of its data.

警告:ポインタの指す先のサイズではなくポインタのサイズが使われた
[(warning)pointerSize]

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
typedef struct {
    char    buf[1024];
} tag_t ;
int main(void){
    tag_t *pointer = malloc(sizeof(pointer));//??
    if(pointer == NULL){
        perror(NULL);
        exit(1);
    }
    free(pointer);
}

malloc()で確保しているのは
ポインタのサイズであって
構造体のサイズではありません。
この例では
ILP32モードの時は4byte,
LP64モードの時は8byteしか
メモリを確保していないません。


●修正案 malloc(sizeof(*ptr))

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
typedef struct {
    char    buf[1024];
} tag_t ;
int main(void){
    tag_t *pointer = malloc(sizeof(*pointer));//*を追加
    if(pointer == NULL){
        perror(NULL);
        exit(1);
    }
    free(pointer);
}


ポインタの指す先のサイズ=構造体のサイズを確保するのであれば
malloc(sizeof(pointer)); ではなくて
malloc(sizeof(pointer));です。

参考:

EXP01-C. ポインタが参照する型のサイズを求めるのにポインタのサイズを使わない

https://www.jpcert.or.jp/sc-rules/c-exp01-c.html

■ 誤って第三引数で比較した

warning: size argument in ‘memcmp’ call is a comparison

memcmpの第三引数が比較式
[-Wmemsize-comparison]

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

int main(void){
    char buf[] = "abc";
    if(strncmp(buf,"abc",3 == 0)){
        puts("1来ません\n");
    }
    if(strncmp(buf,"abc",strlen(buf) == 0)){
        puts("2来ません\n");
    }
    if(memcmp(buf,"abc",sizeof(buf) == 0)){
        puts("3来ません\n");
    }
}

if(strncmp(buf,”abc”,3 == 0)){

if(memcmp(buf,”abc”,3 == 0)){

閉じ丸括弧の位置が違います。