4

我正在完成用于安全字符串检索的函数,并决定打开编译器警告,看看我的任何代码是否引发了任何标志。

目前,我在 Pelles C IDE 上收到以下编译器警告:

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 = 0x00. 那不应该使指针str不再悬空吗?它与我的tmp指针有关吗?我没有释放或设置tmp为任何一个,因为如果失败0x00它应该已经是。但是我是否应该将其设置为成功,因为它在技术上仍然准确地指出了哪里需要和不再需要?0x00realloc0x00str

简而言之:

  1. 为什么我的编译器警告str可能悬空?
  2. 如何删除警告?
  3. tmp是否正确处理了我的指针?
4

1 回答 1

1

只是为了说明我的观点:

#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;
}

现在,如果您的编译器支持内联,对 myrealloc() 的调用将被替换为与原始代码等效的代码,并且实际的 myrealloc() 函数实际上将消失。(检查反汇编的输出)。

于 2012-09-05T21:00:16.570 回答