适当的内存分配?
如何在不知道函数的参数有多大的情况下,如何分配尽可能多的内存呢?
通常,我会使用固定大小,并使用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); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |