【问题标题】:Out-of-memory failure handling method内存不足故障处理方法
【发布时间】:2012-11-26 15:07:29
【问题描述】:

我正在实现一个函数,我希望它是一个“库质量”函数:

char** str_cat(char** const  str, const char * const other ){

    if(str==NULL) 
        return NULL;
    if(other==NULL) 
        return str;
    if(*str==NULL) 
        return str_cpy(str,other);

    char* tmp=(char*)calloc(1,strlen(*str)+strlen(other)+1);
    if(tmp==NULL) 
            return NULL;
    strcat(strcpy(tmp,*str),other); 
    *str=tmp;
    return str;     
}

这是 strcat() 函数的一个版本(不同的签名),可处理任何极端用例。 但是,我的内存不足故障处理方法不适用于大量使用丰富的 str_xxx() API 库的大型应用程序。

问题:有没有更好的解决方案?

【问题讨论】:

  • “不会很好”是什么意思?另外,我认为你有一些内存泄漏?
  • @Xymotech:内存泄漏-我猜问题是我没有释放第一个参数并分配一个新块。如果是这样,因为第一个参数是 char**(指向字符串的指针),而且它可能是指向代码段字符串的指针,所以我选择不处理它。
  • 好吧,如果您在担心内存泄漏之前担心内存不足的情况,那么我认为您的优先级混淆了。
  • @Xymotech:“不会很好” - 我认为也许在低级别上有更好的解决方案。
  • 在我对 API 的定义中,这是用户对释放该块的不负责任(再次:这是 char** 原始块指针没有丢失,而且,我无法释放代码段块:))。

标签: c memory memory-management out-of-memory


【解决方案1】:

我建议malloc 的包装器,比如说xmalloc(或calloc 的等价物),它返回NULL,使内存不足的情况成为应用程序的责任 - 或终止应用程序。对于健壮的、可移植的库来说,前者是一个不错的选择。然而,在现代操作系统的背景下,后者是相当合理的。当发生 OOM 错误时,应用程序会遇到严重问题,并且可能无论如何都无法恢复。 xmalloc 可能会尝试执行一些清理、保存关键数据等。

【讨论】:

    【解决方案2】:

    最好不要更改或释放参数,而是返回一个新分配的字符串:

    char * mycatcat(char *one, char *two)
    {
    size_t len1, len2;
    char *new;
    
    if (!one && !two) return NULL;
    len1 = (one) ? strlen (one) : 0;
    len2 = (two) ? strlen (two) : 0;
    
    new = malloc(1+ len1+ len2);
    if (!new) return NULL;
    
    if (len1) memcpy (new, one, len1);
    if (len2) memcpy (new+len1, two, len2);
    new[len1+len2] = 0;
    
    return new;
    }
    

    顺便说一句:如果字符串 1 或 2 不是由 malloc() 获得的 not,此函数也应该起作用;因此不应该被释放。这样的

    char *onetwo;
    onetwo = my_catcat( "eins", "zwo");
    

    应该可以。 (将 const 添加到参数中以获得额外的乐趣)

    【讨论】:

    • 漂亮优雅。但是:如果只有一个参数是 NULL,我将返回另一个(非 NULL)字符串作为新分配的字符串。其次,最重要的内存不足故障处理与我的相同,我正在寻找一些替代方案:)
    • 您可以轻松地将您的函数重新定义为这个函数的包装器。你甚至可以保持泄漏。
    • 顺便说一句:如果您仔细观察,您会发现如果其中一个参数为 NULL,上述代码会返回“另一个”字符串的副本。 (如果两者都为 NULL,则为 NULL)
    • 你怎么看,我无论如何都不会返回NULL。如果两者都是 NULL 我返回空字符串。
    • 你可以这样做,但是如果你不能为空字符串分配内存怎么办?
    猜你喜欢
    • 2021-12-07
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2022-01-22
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多