C を再学習splint
し、ソース コードのテストに使用しています。
私は次のことをしようとしています:
- 「コンストラクター」関数で構造体を作成する
- 構造体のメモリを解放する「デストラクタ」関数で構造体を破壊します。
ただし、スプリントを使用してコードをテストすると、デストラクタ内の一時ストレージに関連する警告が表示され、デストラクタを呼び出した後にメモリ リークが発生します。
(a) コードのメモリ リークについて splint が正しいかどうか (そうではないと思います)、(b) コードを修正するか、splint に自分のしていることを理解させるにはどうすればよいか、疑問に思っています。
とにかく、ここにコードがあります:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
// define the structure
struct Boring {
int amount;
};
// the creator
static struct Boring *Boring_create(int amount) {
struct Boring *really = malloc(sizeof(struct Boring));
assert(really != NULL);
really->amount=amount;
return really;
}
// the destroyer
static void Boring_destroy(struct Boring *really) {
assert( really != NULL );
// free the memory of the Boring structure
free(really);
}
int main( /*@unused@*/ int argc, /*@unused@*/ char *argv[]) {
int amount = 5;
struct Boring *tv = Boring_create(amount);
printf("The TV is boring level %d\n",tv->amount);
// destroy the tv!
Boring_destroy(tv);
printf("The TV is now boring level %d\n",tv->amount);
return 0;
}
/* Output */
/*
* $> ./destroytv
* The TV is boring level 5
* The TV is now boring level -538976289 (or 0 depending on OS/compiler)
*/
コードはコンパイルされ、gcc で正常に実行されます。
ただし、スプリントを使用してテストすると、スプリントは次の警告を発行します。
$> splint boringtv.c
destroytv.c: (in function Boring_destroy)
destroytv.c: Implicitly temp storage really passed as only param: free (really)
Temp storage (associated with a formal parameter) is transferred to a new non-temporary reference. The storage may be released or new aliases crated. (Use -temptrans to inhibit warning)
destroytv.c: (in function main)
destroytv.c: Fresh storage tv not released before return
A memory leak has been detcted. Storage allocated locally is not released before the last reference to it is lost (use -mustfreefresh to inhibit warning)
Fresh storage tv created
最初の警告は、考えれば考えるほどわからなくなります。しかし、そのマニュアルについての適切な質問を正当化するのに十分なほどマニュアルを読んでいません。
メモリ リークに関する 2 番目の警告は、メモリが別の場所で解放されていることを splint が認識していないようです。これは私には奇妙に思えます。free()
内で呼び出すと、警告が消えますmain
。
助けてくれてありがとう。警告の行番号などの詳細が役立つかどうかお知らせください。