warning: ‘free’ called on unallocated object ‘自動変数’
警告:自動変数の解放は未定義の動作
[-Wfree-nonheap-object]
■この記事の概要
この記事では、C言語でfree
関数を誤ってスタック領域や部分解放に使用するリスクと、これによるエラーを防ぐための推奨方法を解説しています。
■自動変数を自分でfreeしてはいけません
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int 自動変数 = 1024 ;
printf("%d\n",自動変数);
free(&自動変数);//★ダメ
}
自動変数は
自動的にメモリに配置され、
自動的に解放される変数のことなので、
free関数を使ってプログラマが自分で解放してはいけません。
■スタックはfreeで解放できません
warning: ‘free’ of ‘ptr’ which points to memory not on the heap
警告:ヒープ領域上にないメモリを指す ‘ptr’ をfreeした
[-Wanalyzer-free-of-non-heap]
#include <stdlib.h>
static size_t size ;
int main(void) {
char buf[100];
char *ptr ;
if(size > 100)
ptr = malloc(size) ; //ヒープ領域
else
ptr = buf ; //スタック領域
//
// ~~~~
//
free(ptr) ; //非ヒープ領域をfreeした
}
この例では size が100以下の時はヒープ領域(malloc()された領域)を指していないのに free(ptr) を実行してしまうバグです。
malloc()された領域の時のみfreeするように修正が必要です。
■ヒープ領域の部分freeできません
warning: ‘free’ of ‘&*p.mem1’ which points to memory not on the heap
警告:ヒープ領域上にないメモリを指す
‘&p->mem1’のfree
[-Wanalyzer-free-of-non-heap]
#include <stdlib.h>
struct tag {
int m1;
int m2;
int m3;
} ;
int main(void){
struct tag *p = malloc(sizeof(struct tag)) ;
//
//~
//
free(&(p->m1)) ; //NG部分free
free(&(p->m2)) ; //NG途中free
free(&(p->m3)) ; //NG同上
}
このコードでは
p->m1だけfreeしたいのか、
p の指す先を全部freeしたいのか、
読み手にわかりません。
malloc()した領域を一部だけfreeする事はできません。
全部freeしたい場合は
free(&p->m1) ではなくて
free(p) としてください。
また、
free(&(p->m2))のように途中のfreeもできません。
参考: