2012-09-26 37 views
0

我试图避免使用像sprintf和朋友(安全原因)的事情固定的缓冲区大小,但是,当我改变它使用sizeof为arg2 - > arg1,我的程序文本输出已损坏/无法正确显示/缺少某些部分。使用sizeof与sprintf/vsnprintf破坏文本

具体而言,即:

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

“putbuf”声明如何和在哪里? – ecatmur

+1

您还应该检查打印功能的返回值。 –

+0

如果putbuf是一个数组,sizeof将只返回一个数组的大小。即使在这种情况下,如果它是大小为10的整数数组,sizeof将返回40(假设32位机器的int大小为4)。 – fayyazkl

回答

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; 
} 
+0

。我应该在代码中保留固定的缓冲区大小吗? – user1621581

+0

@ user1621581如果将缓冲区作为参数传递以int []形式(即int数组)形式运行,则仍可以使用大小。请记住返回字节数的大小而不是元素数。所以如果你有一个大小为10的整型数组,sizeof array将返回40(假设为32位整数) – fayyazkl

+1

@ user1621581你应该做的是使用相同的值来分配putbuf,因为你传递给了vsnprintf。例如'#define PUTBUF_SIZE 576 ... putbuf = malloc(PUTBUF_SIZE)... vnsprintf(putbuf,PUTBUF_SIZE ...'...如果putbuf的大小是可变的,那么使用变量。 –

2

可能sizeof计算结果为指针的宽度到您的缓冲区,而不是实际的缓冲区的大小。


另一个建议参见this article应对该:

要分配足够大的字符串,并打印到它(代码都正确的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; 
    } 
    } 
}