指向静态变量的不便之处

jov*_*eha 3 c pointers memory-management

我经常使用便捷函数返回指向静态缓冲区的指针,如下所示:

char* p(int x) {
    static char res[512];

    snprintf(res, sizeof(res)-1, "number is %d", x));

    return res;
}
Run Code Online (Sandbox Code Playgroud)

并将它们作为其他函数的参数在整个地方使用:

...
some_func( somearg, p(6) );
....
Run Code Online (Sandbox Code Playgroud)

然而,这种"便利性"除了不是线程安全之外还有一个恼人的缺点(可能还有更多原因):

some_func( somearg, p(6), p(7) );
Run Code Online (Sandbox Code Playgroud)

上面显然没有做我想要的,因为最后两个参数将指向相同的内存空间.我希望能够在没有太多麻烦的情况下使上述方法正常工作.

所以我的问题是:

我是否有一些神奇的方式来完成我想要的东西而不用繁琐的分配和释放?

*****更新2010-04-20*****

无耻的插头:在这里看看我自己的答案

我想它会起作用,但它也接近于矫枉过正.意见?

AnT*_*AnT 8

嗯,一种广泛使用的方法是在调用者上为结果准备内存缓冲区的责任.呼叫者可以选择最喜欢的方法.

在你的情况下写你p

char* p(char *buffer, size_t max_length, int x) { 
  snprintf(buffer, max_length, "number is %d", x); 
  return buffer; 
} 
Run Code Online (Sandbox Code Playgroud)

并称之为

char buffer1[512], buffer2[512];   
some_func( somearg, p(buffer1, sizeof buffer1 - 1, 6), p(buffer2, sizeof buffer2 - 1, 7) );   
Run Code Online (Sandbox Code Playgroud)

这种方法至少有一个明显的缺点:通常情况下,调用者事先不知道需要为缓冲区分配多少个字符.如果一个好的常量编译时值可用,则很容易,但在更复杂的情况下需要额外的工作,比如提供某种"预计算"功能,将所需的缓冲区大小作为运行时值返回.(该snprintf函数实际上以这种方式工作:您可以使用空缓冲区指针和零缓冲区大小调用它,只是为了确定缓冲区大小而进行虚拟运行).