关于《Windows程序设计(第五版)》中一个实例程序的疑问

     最近一直在看Charlse Petzold的《Windows程序设计》,作为一个新得不能再新的新手,只能先照着书的抄抄源码了,之前的例子一直都很正常,但昨天遇到一个很诡异的BUG。

先看实例源码吧:

  1 /*-----------------------------------------------------------------
  2         ENVIRON.C -- Environment List Box
  3         (c) Charles Petzold,1998
  4         Copy by XXXX,2015/1/26
  5 ------------------------------------------------------------------*/
  6 
  7 #include <windows.h>
  8 
  9 #define ID_LIST 1
 10 #define ID_TEXT 2
 11 
 12 LRESULT CALLBACK WndProc(HWND hwnd, UINT, WPARAM, LPARAM);
 13 
 14 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 15 {
 16     static TCHAR szAppName[] = TEXT("Environ");
 17     HWND hwnd;
 18     MSG msg;
 19     WNDCLASS wndclass;
 20 
 21     wndclass.style = CS_VREDRAW | CS_HREDRAW;
 22     wndclass.lpfnWndProc = WndProc;
 23     wndclass.cbClsExtra = 0;
 24     wndclass.cbWndExtra = 0;
 25     wndclass.hInstance = hInstance;
 26     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 27     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 28     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 29     wndclass.lpszMenuName = NULL;
 30     wndclass.lpszClassName = szAppName;
 31 
 32     if (!RegisterClass(&wndclass))
 33     {
 34         MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
 35         return 0;
 36     }
 37 
 38     hwnd = CreateWindow(szAppName, TEXT("Environment List Box"), WS_OVERLAPPEDWINDOW,
 39         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
 40     ShowWindow(hwnd, iCmdShow);
 41     UpdateWindow(hwnd);
 42 
 43     while (GetMessage(&msg, NULL, 0, 0))
 44     {
 45         TranslateMessage(&msg);
 46         DispatchMessage(&msg);
 47     }
 48     return msg.wParam;
 49 }
 50 
 51 
 52 void FillListBox(HWND hwndList)
 53 {
 54     int iLength;
 55     TCHAR * pVarBlock, *pVarBeg, *pVarEnd, *pVarName;
 56     pVarBlock = GetEnvironmentStrings();    //Get pointer to environment block
 57 
 58     while (*pVarBlock)
 59     {
 60         if (*pVarBlock != '=')    //Skip variable names begining with '='
 61         {
 62             pVarBeg = pVarBlock;    //Beging of variable name
 63             while (*(pVarBlock++) != '=');    //Scan until '='
 64             pVarEnd = pVarBlock - 1;    //Points to '=' sign
 65             iLength = pVarEnd - pVarBeg;    //Length of variable name
 66 
 67             //Allocate memory for the variable name and terminating
 68             //zero.Copy the variable name and append a zero
 69             pVarName = calloc(iLength + 1, sizeof(TCHAR));
 70             CopyMemory(pVarName, pVarBeg, iLength * sizeof(TCHAR));
 71             pVarName[iLength] = '';
 72 
 73             //Put the variable name int the list box and free memory
 74             SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)pVarName);
 75             free(pVarName);
 76         }
 77         while (*pVarBlock++ != '');    //Scna until terminating zero
 78 
 79     }
 80     FreeEnvironmentStrings(pVarBlock);    
 81     int code;
 82     code = GetLastError();
 83 }
 84 
 85 
 86 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 87 {
 88     static HWND hwndList, hwndText;
 89     int iIndex, iLength, cxChar, cyChar;
 90     TCHAR * pVarName, *pVarValue;
 91 
 92     switch (message)
 93     {
 94     case WM_CREATE:
 95         cxChar = LOWORD(GetDialogBaseUnits());
 96         cyChar = HIWORD(GetDialogBaseUnits());
 97 
 98         //Create listbox and static text windows
 99         hwndList = CreateWindow(TEXT("listbox"), NULL, WS_CHILD | WS_VISIBLE | LBS_STANDARD,
100             cxChar, cyChar * 3, cxChar * 16 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 5, hwnd,
101             (HMENU)ID_LIST, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
102         hwndText = CreateWindow(TEXT("static"), NULL, WS_CHILD | WS_VISIBLE | SS_LEFT, cxChar, cyChar,
103             GetSystemMetrics(SM_CXSCREEN), cyChar, hwnd, (HMENU)ID_TEXT,
104             (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);
105         FillListBox(hwndList);
106         return 0;
107 
108 
109     case WM_SETFOCUS:
110         SetFocus(hwndList);
111         return 0;
112 
113 
114     case WM_COMMAND:
115         if (LOWORD(wParam) == ID_LIST&&HIWORD(wParam) == LBN_SELCHANGE)
116         {
117             //Get current selectiong
118             iIndex = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
119             iLength = SendMessage(hwndList, LB_GETTEXTLEN, iIndex, 0) + 1;
120             pVarName = calloc(iLength, sizeof(TCHAR));
121             SendMessage(hwndList, LB_GETTEXT, iIndex, (LPARAM)pVarName);
122 
123             //Get environment string
124             iLength = GetEnvironmentVariable(pVarName, NULL, 0);
125             pVarValue = calloc(iLength, sizeof(TCHAR));
126             GetEnvironmentVariable(pVarName, pVarValue, iLength);
127 
128             //Show it in window
129             SetWindowText(hwndText, pVarValue);
130             free(pVarName);
131             free(pVarValue);
132         }
133         return 0;
134 
135 
136     case WM_DESTROY:
137         PostQuitMessage(0);
138         return 0;
139     }
140     return DefWindowProc(hwnd, message, wParam, lParam);
141 }

编译什么的都没有错误提示,但是在本地调试时提示触发一个断点,但是我确定我没有下过断点!!!

提示如图:

选择“继续”后会又提示一个中断,提示堆被损坏

作为一个小彩笔,真心弄不懂,求教大牛!!!

原文地址:https://www.cnblogs.com/lyfh/p/4254344.html