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));

それがポインターの場合、システム上のポインターのサイズになるため、おそらく4または8になります(現時点では4または8が一般的ですが、すべてポインターのサイズによって異なります)。

ほとんどの場合、配列はポインターに分解されることに注意してください。

例えば:

#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、実際のバッファのサイズではなく、バッファへのポインタの幅に評価されます。


これに対処するための別の提案については、この記事を参照してください。

十分な大きさの文字列を割り当てて印刷するには(glibc2.0とglibc2.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 に答える