加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

适当的内存分配?

发布时间:2020-12-16 09:29:58 所属栏目:百科 来源:网络整理
导读:如何在不知道函数的参数有多大的情况下,如何分配尽可能多的内存呢? 通常,我会使用固定大小,并使用sizeof计算其余部分(注意:代码不应该有意义,但要显示问题): #include stdarg.h#include stdio.h#include stdlib.hint test(const char* format,...){ char*
如何在不知道函数的参数有多大的情况下,如何分配尽可能多的内存呢?

通常,我会使用固定大小,并使用sizeof计算其余部分(注意:代码不应该有意义,但要显示问题):

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

int test(const char* format,...)
{
    char* buffer;
    int bufsize;
    int status;
    va_list arguments;
    va_start(arguments,format);
    bufsize = 1024; /* fixed size */
    bufsize = sizeof(arguments) + sizeof(format) + 1024;
    buffer = (char*)malloc(bufsize);
    status = vsprintf(buffer,format,arguments);
    fputs(buffer,stdout);
    va_end(arguments);
    return status;
}

int main()
{
    const char* name = "World";
    test("Hello,%sn",name);
    return 0;
}

但是,我不认为这是要走的路……所以,我如何在这里正确计算所需的缓冲区大小?

解决方法

如果你有vsnprintf可用,我会利用它.它可以防止缓冲区溢出,因为您提供了缓冲区大小,并返回所需的实际大小.

因此,分配您的1K缓冲区然后尝试使用vsnprintf写入该缓冲区,限制大小.如果返回的大小小于或等于缓冲区大小,那么它可以工作,你可以只使用缓冲区.

如果返回的大小大于缓冲区大小,则调用realloc以获取更大的缓冲区并再次尝试.如果数据没有改变(例如,线程问题),第二个将正常工作,因为你已经知道它有多大.

如果您仔细选择默认缓冲区大小,这是相对有效的.如果您的绝大多数输出??都在此限制范围内,则必须进行少量重新分配(请参阅下面的可能的优化).

如果你没有vsnprintf-type函数,我们之前使用的技巧是打开/ dev / null的文件句柄并将其用于相同的目的(在输出到缓冲区之前检查大小).使用vfprintf到该文件句柄来获取大小(输出转到位桶),然后根据返回值分配足够的空间,并将vsprintf分配给该缓冲区.同样,它应该足够大,因为你已经找到了所需的尺寸.

对上述方法的优化是对1K块使用本地缓冲区而不是分配的缓冲区.这避免了在不必要的情况下使用malloc,假设您的堆栈可以处理它.

换句话说,使用类似的东西:

int test(const char* format,...)
{
    char buff1k[1024];
    char *buffer = buff1k; // default to local buffer,no malloc.
    :
    int need = 1 + vsnprintf (buffer,sizeof (buff1k),arguments);
    if (need > sizeof (buff1k)) {
        buffer = malloc (need);
        // Now you have a big-enough buffer,vsprintf into there.
    }

    // Use string at buffer for whatever you want.
    ...

    // Only free buffer if it was allocated.
    if (buffer != buff1k)
        free (buffer);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读