我在程序中遇到了一个让我有些难过的问题。我有一个运行良好的程序(它在 VS 2010 上运行良好,这不是我升级到 .NET 并且这个错误开始发生后)的程序主要是 c 和一些 c++(我的老板讨厌面向对象,因为它通常涉及调用他偏执的库,微软将停止支持,如果他们有旧版本,也必须将其交付给客户,这可能是一个问题,因为其中很多是政府,他还认为这些调用导致不必要的开销,所以我必须尽量避免它)然后我取消注释了一段代码(我将把这个代码块发布得低一点,因为它已经从我未注释的原始代码中修改了一些)开始处理它并得到错误“
我试图通过实施一些不太好的修复来找出问题所在,因为如果一个有效的修复,我将知道实际问题是什么,然后有一个良好的调试基础起点。首先,我尝试增加 std 的大小以使其足够大,以至于我不会放置比它可以处理的更大的字符串(它的值来自列表视图中不超过 3 列,每个列都不能大于 80 个字符),即使这让我更少地得到错误,我仍然得到它。
所以我尝试将该代码块中的 std 切换为 msg(与当时的 std 完全相同)以查看 msg 是否有相同的错误(这意味着它是由该代码块产生的)但错误仍然出现围绕标准。
case IDC_TXT:
//FileSaveBox(hwnd, L"Save as...",L"Text Files (*.txt)\0*.txt\0All Files\0*.*\0",L"*.txt",wFileName);
FileSaveBox(hwnd, L"Save as...",L"CSV (Coma delimited) (*.csv)\0*.csv\0All Files\0*.*\0",L"*.csv",wFileName);
if(wcslen(wFileName)==0) return 0;
fin.open(wFileName);
if(fin.is_open())
val=MessageBox(hwnd,L"This file allready exists. Do you want to overwrite it?",L"Confirm Save", MB_YESNO);
fin.close();
if (val == IDNO)
return 0;
fout.open(wFileName);
if(!fout.is_open()) return 0;
/*if ((fp = _wfopen (wFileName, L"w"))==NULL)
{
Message("Cannot Open File");
return 0;
}*/
_swprintf(msg,L"Some string");
if(im.col3)
wcscat(msg,L", another string");
fout << msg << L"\n";
count = ListView_GetItemCount(hlvim);
for(i=0;i<count;i++)
{
ListView_GetItemText(hlvim,i,0,msg,240);
wcscat(msg,L", ");
ListView_GetItemText(hlvim,i,1,temp,80);
wcscat(msg,temp);
if(im.col3)
{
wcscat(msg,L", ");
ListView_GetItemText(hlvim,i,2,temp,80);
wcscat(msg,temp);
}
fout << msg << L"\n";
//fprintf(fp,"%s\n",msg);
}
//fclose(fp);
fout.close();
SetFocus(hwnd);
return 0;
这让我觉得也许它只是在 std 周围的金丝雀上写了一些其他变量,所以我在用 msg 替换它的所有实例后将其注释掉(对于那些它是尚未得到的函数的局部变量的执行当错误发生时调用)但这只是导致错误出现在 msg 周围(实际上也显示为函数的局部变量)。
接下来,我尝试使用 static 在堆而不是堆栈上声明 msg(因为使用 new 会涉及到我的老板非常讨厌现代代码),但这只会导致以下错误发生:“HTZx86.exe 中 0x00300030 处的未处理异常:0xC0000005:访问冲突读取位置 0x00300030。” 在位置 0x00300030 是对我无法控制的外部 API 的调用。
现在,在我对代码的其他部分进行了一些不相关的修改之后,我同时随机获得了 std 和 msg 周围的堆栈错误(有时在函数调用之后,有时在之前),而不是在一致的基础上。我想知道是否有任何好的方法来调试这个问题,因为单独的断点对我没有帮助,调用堆栈也没有帮助(尽管我可能使用错误)?
下面是变量的声明,也是在调用函数之前唯一可以调用的地方:
声明:
int i,j,k,count,val,ntx,nrx,IsActive, rxcount;
BOOL callsign, map2rx, rxhit;
double f1,f2,f3;
WCHAR str[80];
static WCHAR msg[240];
WCHAR temp[80];
static short dir;
//FILE* fp;
std::wofstream fout;
std::wifstream fin;
LV_COLUMN pcol;
LV_ITEM pit, pit2;
static HWND hlvtx;
static HWND hlvrx;
static HWND hlvim;
和其他电话:
count = ExternalAPIFunction2t();
for(i=0;i<count;i++)
{
ntx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBTXCH));
nrx = _wtoi(ExternalAPIFunction1(i+1,_SP_NBRXCH));
IsActive = _wtoi(ExternalAPIFunction1(i+1,_SP_ISACTIVE));
try
{
for(j=0;j<ntx && IsActive;j++)
{
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_TXCH01+j));
_swprintf(msg,L"%09.4f MHz",f1);
pit.mask = LVIF_TEXT|LVIF_PARAM;
pit.iItem = j;
pit.iSubItem = 0;
pit.lParam = j;
wcscpy_s(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
wcscat_s(msg,L"_CH");
_itow(j+1,temp,80);
wcscat_s(msg,temp);
pit.pszText = msg;
ListView_InsertItem(hlvtx,&pit);
_swprintf(msg,L"%.4f",f1);
pit.mask = LVIF_TEXT;
pit.iSubItem = 1;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_NOMINALPOWER));
_swprintf(msg,L"%.1f",f1);
pit.iSubItem = 2;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
_swprintf(msg,L"%f",i+1);
pit.iSubItem = 3;
pit.pszText = msg;
ListView_SetItem(hlvtx,&pit);
}
}catch(std::exception &e)
{
MessageBox(hwnd,(wchar_t*) e.what(),L"Error", MB_OK);
}
for(j=0;j<nrx && IsActive;j++)
{
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXCH01+j));
pit.mask = LVIF_TEXT|LVIF_PARAM;
pit.iItem = j;
pit.iSubItem = 0;
pit.lParam = j;
wcscpy(msg,ExternalAPIFunction1(i+1,_SP_CALLSIGN));
wcscat(msg,L"_CH");
_itow(j+1,temp,10);
wcscat(msg,temp);
pit.pszText = msg;
ListView_InsertItem(hlvrx,&pit);
_swprintf(msg,L"%.4f",f1);
pit.mask = LVIF_TEXT;
pit.iSubItem = 1;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
f1 = _wtof(ExternalAPIFunction1(i+1,_SP_RXBANDWIDTH));
_swprintf(msg,L"%.2f",f1);
pit.iSubItem = 2;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
_swprintf(msg,L"%f",i+1);
pit.iSubItem = 3;
pit.pszText = msg;
ListView_SetItem(hlvrx,&pit);
}
}
PS ExternalAPIFunction1 是存在访问冲突的那个。