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ポインタになる保証がありません。
参考:
●修正案 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しか
メモリを確保していないません。
●修正案3 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