Windows: Buffer too small

Gast #2666143
Lesenswert?

Guten Tag,

ich habe aus dem Buch "C - Einführung und professionelle Anwendung" 
folgendes Beispiel in Visual C++ 2008 Express eingegeben:
1
#include <stdio.h>
2
#include <windows.h>
3

4
HINSTANCE hInst = 0;
5
char szAppName[] = "Basis";
6
char szTitle[100] = "Willys Titelleiste";
7

8
BOOL InitApplication ();
9
BOOL InitInstance (int);
10
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
11

12
void onPaint (HWND);
13

14
int WINAPI WinMain (  HINSTANCE hInstance,
15
            HINSTANCE hPrevInstance,
16
            LPSTR    lpCmdLine,
17
            int       nCmdShow)
18
{
19

20
  MSG msg;
21
  hInst = hInstance;
22

23
  if (!InitApplication () ) return FALSE;
24
  if (!InitInstance (nCmdShow) ) return FALSE;
25

26
  while (GetMessage (&msg, NULL, 0, 0))
27
  {
28
    TranslateMessage (&msg);
29
    DispatchMessage (&msg);
30
  }
31

32

33

34
  return (msg.wParam);
35
}
36

37
BOOL InitApplication ()
38
{
39
  WNDCLASSEX wc;
40

41
  wc.cbSize = sizeof(WNDCLASSEX);
42
  wc.style = CS_HREDRAW | CS_VREDRAW;
43
  wc.lpfnWndProc = (WNDPROC)WndProc;
44
  wc.cbClsExtra = 0;
45
  wc.cbWndExtra = 0;
46
  wc.hInstance = hInst;
47
  wc.hIcon = LoadIcon ( NULL, IDI_QUESTION);
48
  wc.hCursor = LoadCursor ( NULL, IDC_WAIT);
49
  wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
50
  wc.lpszMenuName = NULL;
51
  wc.lpszClassName = szAppName;
52
  wc.hIconSm = LoadIcon (NULL, IDI_WINLOGO);
53

54
  return RegisterClassEx(&wc);
55
}
56

57

58
BOOL InitInstance (int nCmdShow)
59
{
60
  HWND hWnd;
61
  hWnd = CreateWindow(
62
      szAppName,
63
      szTitle,
64
      WS_OVERLAPPEDWINDOW,
65
      50,//CW_USEDEFAULT,
66
      100,
67
      500,
68
      250,
69
      NULL,
70
      NULL,
71
      hInst,
72
      NULL);
73
  if (!hWnd) return (FALSE);
74
  ShowWindow (hWnd, nCmdShow);
75
  UpdateWindow (hWnd);
76

77
  return (TRUE);
78
}
79

80

81
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
82
{
83
  
84
  switch (message)
85
  {
86
  case WM_PAINT:
87
    onPaint(hWnd);
88
    break;
89
  case WM_DESTROY:
90
    PostQuitMessage(0);
91
    break;
92
  default:
93
    return DefWindowProc (hWnd, message, wParam, lParam);
94
  }
95

96
  return 0;
97
}
98

99

100

101
void onPaint (HWND hWnd)
102
{
103
  PAINTSTRUCT ps;
104
  HDC hdc;
105
  TEXTMETRIC tm;
106
  char szZahl[10];
107

108
  int i = 0;
109
  int nXStart1, nXStart2, nYStart;
110
  int nAveCharWidth, nLineHeight;
111

112
  char* strMetrik[] = {  "Zeichenhoehe: ",
113
              "Hoehe oberhalb der Basislinie:",
114
              "Hoehe unterhalb der Basislinie:",
115
              "Hoehe des Bereichs fuer Umlaute:",
116
              "Abstand zwischen den Zeilen:",
117
              "Mittlere Zeichenbreite:",
118
              "Maximale Zeichenbreite:"
119
            };
120

121
  hdc = BeginPaint (hWnd, &ps);
122

123
  GetTextMetrics(hdc, &tm);
124
  nLineHeight = (int)(tm.tmHeight + tm.tmExternalLeading)+2;
125
  nAveCharWidth = (int)tm.tmAveCharWidth;
126

127
  nXStart1 = 5*nAveCharWidth;
128
  nXStart2 = nXStart1 + 40*nAveCharWidth;
129

130
  nYStart = 1*nLineHeight;
131

132
  for (i=0; i < 7; i++)
133
  {
134
    TextOut (hdc, nXStart1, nYStart, strMetrik[i], strlen(strMetrik[i]) );
135

136
    switch(i)
137
    {
138
    case 0: sprintf_s(szZahl, "%31d", tm.tmHeight);
139
        break;
140
    case 1: sprintf_s(szZahl, "%31d", tm.tmAscent);
141
        break;
142
    case 2: sprintf_s(szZahl, "%31d", tm.tmDescent);
143
        break;
144
    case 3: sprintf_s(szZahl, "%31d", tm.tmInternalLeading);
145
        break;
146
    case 4: sprintf_s(szZahl, "%31d", tm.tmExternalLeading);
147
        break;
148
    case 5: sprintf_s(szZahl, "%31d", tm.tmAveCharWidth);
149
        break;
150
    case 6: sprintf_s(szZahl, "%31d", tm.tmMaxCharWidth);
151
        break;
152
    };
153

154
    TextOut(hdc, nXStart2, nYStart, szZahl, strlen(szZahl) );
155
    nYStart += nLineHeight;
156

157
  }
158

159
  EndPaint (hWnd, &ps);
160
}


Ich erhalte folgende Fehlermeldung:

Debug Assertion Failed!
Program
...ges\textmetric\Debug\textmetric.exe
File f:\dd\vctools\crt_bld\self_x86\crt\src\vsprintf.c
Line 244
Expression:("Buffer too small", 0)



Kann mir jemand sagen, woran das liegt?


LFX3
#2666253
Lesenswert?

LFX3 schrieb:

>
1
> case 0: sprintf_s(szZahl, "%3ld", tm.tmHeight);
2
>

Es muss vor allen Dingen
1
sprintf_s( szZahl, sizeof(szZahl), "%3ld", tm.tmHeight);
heissen.
Auch wenn Microsoft mittels Template ...
1
template <size_t size>
2
int sprintf_s(
3
   char (&buffer)[size],
4
   const char *format [,
5
      argument] ... 
6
); // C++ only
... eine Automatik eingebaut hat, die dann greift, wenn der Compiler das 
Array selber sehen kann. Denn irgendwann hast du dann diesen Fall nicht 
mehr und dann ist das Kopfkratzen groß, was denn das Problem ist. Nichts 
gegen Komfort, aber zuviel Komfort macht nachlässig.

Und ob die "ld" richtig sind, muss man in der TEXTMETRIC Struktur 
nachsehen. Das steht
1
typedef struct tagTEXTMETRIC {  /* tm */
2
    int  tmHeight;
3
    int  tmAscent;
4
    int  tmDescent;
5
    int  tmInternalLeading;
6
    int  tmExternalLeading;
7
    int  tmAveCharWidth;
8
    int  tmMaxCharWidth;
9
    int  tmWeight;
10
    BYTE tmItalic;
11
    BYTE tmUnderlined;
12
    BYTE tmStruckOut;
13
    BYTE tmFirstChar;
14
    BYTE tmLastChar;
15
    BYTE tmDefaultChar;
16
    BYTE tmBreakChar;
17
    BYTE tmPitchAndFamily;
18
    BYTE tmCharSet;
19
    int  tmOverhang;
20
    int  tmDigitizedAspectX;
21
    int  tmDigitizedAspectY;
22
} TEXTMETRIC;

Nö. ld ist definitiv falsch. tmHeight ist vom Datentyp int. Also muss 
der Formatspecifier ein "d" sein und kein "ld".


Leg das Buch zur Seite und kauf dir erst mal ein vernünftiges 
Einsteigerbuch für C. Der Klassiker "Kernighan&Ritchie" wird immer 
wieder gerne genommen.
Wenn du den durch hast und auch verstehst, dann fallen dir die Fehler in 
diesem Buch dann auch auf. Alleine der Titel muss schon stutzig machen. 
Zwischen "Einführung" und "professioneller Anwendung" liegen im 
günstigen Fall so ca. 3 bis 4 Jahre und eine halbes Bücherregal an 
Literatur.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren