0

我试图避免使用 sprintf 和朋友(安全原因)之类的固定缓冲区大小,但是,当我将其更改为对 arg2 -> arg1 使用 sizeof 时,我的程序文本输出已损坏/无法正确显示/缺少某些部分。

具体来说,即:

vsnprintf(putbuf, LARGE_BIG_BUFFER_SIZE, format, args);

vsnprintf(putbuf, sizeof putbuf, format, args); 

通过简单的 sizeof 更改,我的文本输出全部损坏/短。我错过了什么吗?

原始功能:

to_screen(const char *format,...)
{
        if (window_display && format) {
                va_list args;
                va_start(args, format);
                vsnprintf(putbuf, LARGE_BIG_BUFFER_SIZE, format, args);
                va_end(args);
        }
}
4

2 回答 2

3

将您的代码放在某处:

printf ("size is %d\n", sizeof (putbuf));

如果它是一个指针,您可能会得到四个或八个,因为这将是您系统上指针的大小(目前四个或八个将是常见的,但这完全取决于指针的大小)。

请记住,在绝大多数情况下,数组会衰减为指针。

例如:

#include <stdio.h>

void fn (char x[]) {
    printf ("size in fn = %zd\n", sizeof (x));
}

int main (void) {
    char x[100];
    printf ("size in main = %zd\n", sizeof (x));
    fn (x);
    return 0;
}

在我的系统上输出:

size in main = 100
size in fn = 4

如果你想传递实际的尺寸信息,你需要明确地这样做:

#include <stdio.h>

void fn1 (char x[]) {
    printf ("size in fn1 = %zd\n", sizeof (x));
}

void fn2 (char x[], size_t szx) {
    printf ("size in fn2 = %zd\n", szx);
}

int main (void) {
    char x[100];
    printf ("size in main = %zd\n", sizeof (x));
    fn1 (x);
    fn2 (x, sizeof (x));
    return 0;
}

或者,对于分配的内存:

#define SZ 512
int main (void) {
    char *x = malloc (SZ);   // warning, may fail, irrelevant here.
    printf ("size in main = %zd\n", sizeof (x));
    fn2 (x, SZ);
    free (x);
    return 0;
}
于 2012-09-26T09:46:47.240 回答
2

可能sizeof评估指向缓冲区的指针的宽度,而不是实际缓冲区的大小。


有关解决此问题的另一个建议,请参见本文:

分配足够大的字符串并打印到其中(glibc 2.0 和 glibc 2.1 的代码都正确):

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

char * make_message(const char *fmt, ...) {
  /* Guess we need no more than 100 bytes. */
  int n, size = 100;
  char *p, *np;
  va_list ap;

  if ((p = malloc (size)) == NULL)
    return NULL;

  while (1) {
    /* Try to print in the allocated space. */
    va_start(ap, fmt);
    n = vsnprintf (p, size, fmt, ap);
    va_end(ap);
    /* If that worked, return the string. */
    if (n > -1 && n < size)
       return p;
    /* Else try again with more space. */
    if (n > -1)    /* glibc 2.1 */
       size = n+1; /* precisely what is needed */
    else           /* glibc 2.0 */
       size *= 2;  /* twice the old size */
    if ((np = realloc (p, size)) == NULL) {
       free(p);
       return NULL;
    } else {
       p = np;
    }
  }
}
于 2012-09-26T09:43:38.230 回答