2017-01-30 6 views
2

以下のfreeSマクロでポインタの変数リストを解放したいと思っています:freeS(s1、s2、...);Freeはva_argリストとして送信されたポインタを解放しません

私のコードは、freeSF関数からの最初のポインタアドレスで印刷を取得しても、最初のポインタを解放しません。 メインでは、フリー(s1)が動作しますが、それはすべきです。期待どおりのメインクラッシュでフリー(s2)。

freeSF関数でs1ポインタを解放するにはどうすればよいですか?

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

#define freeS(...) freeSF("", __VA_ARGS__, NULL) 
void freeSF(char *paramType, ...) { 
    va_list pl; 

    va_start(pl, paramType); 
    paramType = va_arg(pl, char *); 
    while (paramType) { 
     printf("arg %p\n", paramType); 
     free(paramType); 
     paramType = va_arg(pl, char *); 
    } 
    va_end(pl); 
} 

int main(int ARGC, char** ARGV) { 
    char *s1 = strdup("1"); 
    char *s2 = strdup("2"); 
    printf("s1 %p, s2 %p\n", s1, s2); 
    freeS(s1, s2); 
    free(s1); 
} 
+2

あなたはしています: 'freeS(s1、s2)' '次に' free(s1) 'をしています。あなたは二重自由です。 http://ideone.com/shZ3Scはうまく動作します。あなたはそれが解放されていないことをどのように知っていますか? – Brandon

+0

ポインタがdoubleの場合、エラーがあります。 './a.out 'のエラー:ダブルフリーまたは破損(fasttop):0x00000000024c5030。それは無料でしか起こらない – Remy

+0

それはエラーを引き起こさない:http://ideone.com/2sQPXlあなたはまだ 'free'を2回呼んでいて、それは未定義の振る舞いです。' free(s1)あなたがすでに 'freeS(s1、s2)'をしているときに 'free(s2)'を呼び出すことができます。 – Brandon

答えて

6

ダブルフリーであるため、プログラムはundefined behaviorと表示されます。

未定義の動作では、何かが起こる可能性があります。プログラムがクラッシュしたり、奇妙な結果が出力されたり、(この場合は)正しく動作するように見えるかもしれません。 printfの呼び出しや未使用のローカル変数の追加など、一見無関係な変更を追加すると、未定義の動作がどのように現れるかを変更できます。

この場合、mainfree(s1)をコールしてもクラッシュすることはありません。まだ未定義の動作です。たとえば、このコードを実行するとクラッシュしません。しかし、free(s1)を呼び出す直前にmallocへのコールを追加すると、クラッシュします。

コードがクラッシュしても意味しないので、となります。

+0

正解ですが、私は同じことを書いていましたが、なぜOPコードではなく、メインで 'free(s1)'が倍増するのかという理由が考えられました。それについてのアイデアはありますか? – LPs

+0

@ LPS;これは定義されていない動作自体の定義です。 OPのコードは、MAYまたはMAY-エラーを引き起こすことはありません。これは未定義です。それは彼のために働くかもしれない、そうでないかもしれない。 – Brandon

+0

@Brandonまあ、私は知っている....好奇心の外:このUBが説明可能な行動を持っている場合。 @LPs; – LPs

関連する問題