【问题标题】:Using Realloc in C在 C 中使用 Realloc
【发布时间】:2012-01-09 07:00:09
【问题描述】:

它确实是关于使用 realloc 的一些建议的帖子,更具体地说,如果我可以利用它来简化我现有的代码。本质上,下面的内容是动态分配一些内存,如果我超过 256,那么数组需要增加大小,所以我 malloc 一个临时数组,大小为 2 倍,memcpy 等(见下文)。

我只是想知道是否可以在下面的代码中使用 realloc,以简化它,非常感谢任何建议、示例代码,甚至是关于如何实现它的提示!

干杯。

void reverse(char *s) {
char p;

switch(toupper(s[0])) 
{
    case 'A': case 'E': case 'I': case 'O': case 'U':
        p = s[strlen(s)-1];
        while( p >= s )
            putchar( p-- );
        putchar( '\n' );
        break;
    default:
        printf("%s", s);
        break;
}
printf("\n");
    }

    int main(void) {
char c;
int buffer_size = 256;
char *buffer, *temp;
int i=0;

buffer = (char*)malloc(buffer_size);
while (c=getchar(), c!=' ' && c!='\n' && c !='\t') 
{
    buffer[i++] = c;
    if ( i >= buffer_size )
    {
        temp = (char*)malloc(buffer_size*2);
        memcpy( temp, buffer, buffer_size );
        free( buffer );
        buffer_size *= 2;
        buffer = temp;
    }
}
buffer[i] = '\0';
reverse(buffer);

return 0;

}

【问题讨论】:

  • 风格说明:您应该更喜欢 not 转换 malloc 的返回值。
  • reverse 应该将参数作为const char *

标签: c memory dynamic realloc


【解决方案1】:

是的是简短的回答。下面是它的外观:

if ( i >= buffer_size )
{
    temp = realloc(buffer, buffer_size*2);
    if (!temp)
        reportError();
    buffer_size *= 2;
    buffer = temp;
}

注意,你仍然需要使用一个临时指针来保存realloc()的结果;如果分配失败,您仍然拥有指向仍然有效的现有缓冲区的原始 buffer 指针。

【讨论】:

  • 如果我错了,请纠正我,但是buffer=temp,不会复制temp 内存地址吗?所以如果我之后释放temp,我也释放buffer?如果为真,我何时释放 temp 变量以免浪费内存分配两个相同的字符串?抱歉,我正在尝试了解这是如何工作的。
【解决方案2】:

Realloc 几乎正是您正在寻找的东西 - 您可以将 if ( i >= buffer_size ) 中的整个块替换为以下内容:

buffer = (char*)realloc(buffer, buffer_size*2);
buffer_size *= 2;

注意这忽略了错误条件(如果realloc的返回是NULL);捕捉这种情况留给读者。

【讨论】:

    【解决方案3】:

    是的,realloc 可用于稍微简化您的代码。如果您对错误处理不感兴趣,那么:

    char *tmp = malloc(size*2);
    memcpy(temp, buffer, size);
    free(buffer);
    buffer = tmp;
    

    本质上等价于:

    buffer = realloc(buffer, size*2);
    

    如果您对错误处理感兴趣(您可能应该如此),那么您需要检查NULL 返回值。您的原始代码也是如此。

    【讨论】:

    • -1。如果 realloc 失败(返回 NULL),你就失去了对原始块的引用。
    • @Graham:我明确表示“如果你对错误处理不感兴趣”。 OP 在他的原始代码中也没有任何错误处理。
    • 这种“错误处理”不仅仅是像检查std::cin >> n这样的小游戏;这里的这个可能并且几乎肯定会导致 UB...
    【解决方案4】:

    是的,为了简化你的代码,你可以替换

    if ( i >= buffer_size )
    {
        temp = (char*)malloc(buffer_size*2);
        memcpy( temp, buffer, buffer_size );
        free( buffer );
        buffer_size *= 2;
        buffer = temp;
    }
    

    if ( i >= buffer_size )
        buffer = realloc(buffer, buffer_size *= 2);
    

    这不考虑错误检查,因此您需要检查以确保 realloc 不返回 NULL

    【讨论】:

    • realloc 可能会返回 NULL,给你一个即时不可恢复的泄漏。
    • -1。如果 realloc 失败(返回 NULL),你就失去了对原始块的引用。
    • @GrahamBorland 我说你可以用那个代码替换他的原始代码。他没有在那里检查NULL,所以我也没有。但我添加了一个注释来提及它。
    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2023-03-16
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多