2012-09-26 68 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; 
    } 
    } 
}