4

安全な文字列検索のために関数を完成させており、コンパイラの警告を上げて、コードのいずれかがフラグを立てているかどうかを確認することにしました。

現在、PellesCIDEで次のコンパイラ警告を受け取っています。

stringhandle.c(39): warning #2800: Potentially dangling object 'str' used after call to function 'realloc'.
stringhandle.c(50): warning #2800: Potentially dangling object 'str' used after call to function 'realloc'.

これが私の関数です(コードを読む前に質問全体を読みたい場合は、以下を読んでください):

char *getstr(void)
{
    char *str, *tmp;
    int bff = STRBFF, ch = -1, pt = 0;

    if(!(str = malloc(bff)))
    {
        printf("\nError! Memory allocation failed!");
        return 0x00;
    }
    while(ch)
    {
        ch = getc(stdin);
        if (ch == EOF || ch == '\n' || ch == '\r') ch = 0;
        if (bff <= pt)
        {
            bff += STRBFF; 
            if(!(tmp = realloc(str, bff))) 
            {
                free(str);  //line 39 triggers first warning
                str = 0x00;
                printf("\nError! Memory allocation failed!");
                return 0x00;
            }
            str = tmp;
        }
        str[pt++] = (char)ch;
    }
    str[pt] = 0x00;
    if(!(tmp = realloc(str, pt)))
    {
        free(str); //line 50 triggers second warning
        str = 0x00;
        printf("\nError! Memory allocation failed!");
        return 0x00;
    }
    str = tmp;
    return str;
}

strぶら下がっているかもしれないと警告されている理由を理解していると思います。strエラーが発生した場合にポイントされた割り当てられたスペースを解放していますが、str解放された後、関数はそれ以上呼び出すことができません。修正として、私はただやってみて、free(str)続いてstr = 0x00strポインタがぶら下がっていないようにするべきではありませんか?それは私のtmpポインターと関係がありますか?失敗した場合はすでにあるはずなので、私は解放したり、どちらかに設定tmpしたりしません。しかし、それはまだ技術的に正確にどこにあり、もはや必要ではないので、成功に設定する必要がありますか?0x000x00realloc0x00str

要するに:

  1. コンパイラの警告strがぶら下がっている可能性があるのはなぜですか?
  2. 警告を削除するにはどうすればよいですか?
  3. tmpポインタを正しく処理していますか?
4

1 に答える 1

1

Just to illustrate my points:

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

static inline void * myrealloc(void *org, size_t newsize)
{
char * new;
new = realloc(org, newsize);
if (!new) {
        fprintf(stderr, "\nError! Memory allocation failed!\n");
        free (org);
        return NULL;
        }
return new;
}

char *getstr(void)
{
#define STRBFF 256

    char *str = NULL;
    size_t size , used ;

    for (size=used=0; ; ) {
        int ch;
        if (used >=size) {
            str = myrealloc(str, size += STRBFF);
            if(!str) return NULL;
        }
        ch = getc(stdin);
        if (ch == EOF || ch == '\n' || ch == '\r') ch = 0;
        str[used++] = ch;
        if (!ch) break;
    }
    str = myrealloc(str, used);
    return str;
}

Now, if your compiler supports inlining, the calls to myrealloc() will be replaced by the equivalent of your original code, and the actual myrealloc()function will virtually disappear. (check the disassembled output).

于 2012-09-05T21:00:16.570 に答える