用wstring的向量替换了wchar_t指针的向量。
我仍然得到缓冲区溢出,但现在程序中崩溃位置的数量急剧减少。
/****************************************************/
/* */
/* It was the string parser that caused buffer */
/* overflow ! */
/* */
/****************************************************/
必须对矢量进行一些不当使用,但这将留给另一个问题。
对于所有试图提供帮助的人,你从我那里获得+1。
我已经尝试了你的答案,但他们都奏效了。
由于我是初学者,我害怕使用wstring,但感谢社区的帮助,我认为我已经设法学习了一些新东西。
再次感谢大家。
再次感谢大家。
问候。
注:
这是一个简化的描述,以使这个问题尽可能短。
有关详细信息,请询问其他问题,我将提供更多信息。
我有一个包含2个编辑控件,2个按钮和组合框的对话框。
在对话框创建中,在WM_INIDIALOG中,与数据库建立连接,该数据库保存有关员工月薪的数据。
然后将员工的主键加载到组合框中。
表格如下:
Table_Employee< #primary_key,...>
Table_Salary< #pk_salary,$ primary_key,January,February,...,Year>
关系是一对多,因为一个员工每年都有关于月薪的数据,如下所示:
|一月| ...... |年| #pk_salary | $ primary_key | | 1000.51 | ...... | 2012 | 100025558 | 48089989891 | | 2000.51 | ...... | 2013 | 552025558 | 48089989891 | ...
一旦用户从组合框中选择主键,他就可以通过在第一个编辑控件中键入来更改月薪数据,并且他必须在第二个编辑控件中键入年份。
输入的数据保存在如下声明的向量中:
INT_PTR CALLBACK dlgProcedure(HWND hwnd, UINT Message,
WPARAM wParam, LPARAM lParam )
{
static vector<wchar_t*> ee; // vector for monthly salaries and a year
// this vector holds data for all thes
tatic vector< vector<wchar_t*> > Pee; years
...
case WM_INITDIALOG:
{
// 12 months + 1 year = vector of 13 to store data
ee.assign( 13, LoadedValue );
...
用户按下第一个按钮后,月份的数据将保存在上面的矢量中:
case IDC_BUTTON_MONTH:
{
// needed, since we have vector of wchar_t*
wchar_t *temp = new wchar_t[50];
GetDlgItemInt( ... , temp, ... );
UINT i = // ordinal of the month taken from checkbox
ee[ i ] = temp;
然后用户必须输入年份,按下第二个按钮后,它将按如下方式存储:
case IDC_BUTTON_YEAR:
{
wchar_t *temp = new wchar_t[50]; // needed, since we have vector of wchar_t*
GetDlgItemInt( ... , temp, ... );
ee[12] = temp;
// This means that all the data is collected
// so we can store this year’s data in the vector for years
Pee.push_back(ee);
这样,矢量Pee持有所有年份(2012年,2013年......)的数据,而矢量ee保存具体数据(特定年份的月薪)。
在组合框中选择更改后,我必须清除所有向量,以便存储新数据。
当我这样做时,我得到了错误,我的程序会快照。当我试图关闭窗户时也会发生崩溃。
如果我注释掉清除向量的代码部分,我的程序可以工作,但是我不能用它来存储新数据,因为向量没有被正确清除。
在组合框中启动程序并更改选择后,会弹出一个对话框,提供2个调试器,并显示以下消息:
SomeProgramName.exe [3300]中发生未处理的异常。
在Debug中,在MS Visual Studio 2008中,我单击了Exceptions,然后选中了 一切。在调试模式下启动程序后,我得到以下消息的对话框:
这可能是由于堆的损坏,这表示MyProgramName.exe或其加载的任何DLL中存在错误。
这也可能是由于用户在MyProgramName.exe具有焦点时按下F12。
输出窗口可能包含更多诊断信息。
正如我上面所说,在我注释掉清理代码后,错误不再发生。
这就是为什么我非常确定存在我的问题。
WM_CLOSE处理程序:
case WM_CLOSE:
{
// cleanup
for( vector<wchar_t*>::size_type i = 0; i < ee.size(); i++)
delete[] ee[i];
ee.clear();
for( vector< vector<wchar_t*> >::size_type i = 0; i < pee.size(); i++)
for( vector<wchar_t*>::size_type j = 0; j < pee[i].size(); j++)
delete[] pee[i][j];
pee.clear();
DestroyWindow( hDlg );
}
return TRUE;
组合框处理程序:
case IDC_COMBO12:
{
if(HIWORD(wParam) == CBN_SELCHANGE )
{
// cleanup
for( vector<wchar_t*>::size_type i = 0; i < ee.size(); i++)
delete[] ee[i];
ee.clear();
for( vector< vector<wchar_t*> >::size_type i = 0; i < pee.size(); i++)
for( vector<wchar_t*>::size_type j = 0; j < pee[i].size(); j++)
delete[] pee[i][j];
pee.clear();
// assign neutral values to vectors
ee.assign( 13, L”-1” );
for( int i = 2012; i < currentYear; i++ )
Pee.push_back(ee);
// other commands, like loading data from database and so on...
由于我有一个指针向量(vector < wchar_t* >
),我相信我不能只使用clear()
方法清空向量,因为它会导致内存泄漏。
这就是为什么我认为必须首先删除指针,然后才使用clear()
方法。
这是我第一次使用wchar_t*
的向量,所以我问社区我在这里做错了什么?
如何在处理程序中正确重置这些向量?
要求提供更多信息,我很乐意为他们提供。
答案 0 :(得分:5)
因为我有一个指针向量(vector&lt; wchar_t *&gt;)
那里有你的问题。不要使用指针向量。使用std::wstring
的向量。那么你不必担心这一点。
修改:要std::wstring
使用GetDlgItemText
,您可以执行以下操作:
std::vector<std::wstring> ee;
wchar_t wchScratch[1024]; // should be big enough for any string you've added
GetDlgItemText(hWnd, iID, wchScratch, sizeof(wchScratch) / sizeof(wchScratch[0]));
ee.push_back(wchScratch);
或者,如果你想要更复杂的东西,你可以这样做:
int iLength = GetWindowTextLength(GetDlgItem(hWnd, iID));
std::wstring strTemp;
strTemp.resize(iLength + 1);
strTemp.resize(GetDlgItemText(hWnd, iID, &strTemp[0], strTemp.size()));
ee.push_back(strTemp);
基本上,关于如何从控件中获取字符串没有任何变化,您只是在改变存储方式。
答案 1 :(得分:1)
崩溃的原因:您定义vector<wchar_t*>
,使用ee.assign( 13, L”-1” );
和wchar_t *temp = new wchar_t[50];
填充向量,并使用delete[]
删除。所有不匹配。
delete[]
运算符释放堆上分配的内存
ee.assign( 13, L”-1” );
传递编译器分配的对象。那是错的。这些不在堆上,你不应该释放那段记忆,但是当你拨打delete[]
时就这样做了。
您可以将矢量定义为vector<std::wstring>
然后将其用作
std::vector<std::wstring> v;
v.assign(10,L"xyz");
std::wstring s = L"abc";
v.push_back(s);
... etc.
v.clear(); // call destructor for every std::wstring in the vector
在你的按钮处理程序中:
wchar_t temp[50];
GetDlgItemTxt( ... , temp, ... );
v[i] = temp; // creates a wstring object and copies temp in there
你可以像你一样定义你的矢量并使用new和delete但你需要一个很好的理由。您负责为向量中的对象分配的内存。你不能混合在堆上,堆栈上或静态分配的指针(例如字符串文字L“-1”)。
vector<wchar_t*> v;
v.assign(10, 0); // fill in with null pointers
wchar_t *ptr = new wchar_t[10];
... fill in ptr memory with data
v.push_back(ptr);
... etc.
// Now you need to free memory you allocated manually - You do not do that
// in case of std::vector<std::wstring>
for (vector<wchar_t*>::iterator it = v.begin(); it != v.end(); ++it)
delete[] *it;
v.clear(); // clear function calls destructor for every object in the vector.
// There is no destructor for a pointer, hence the difference between
// deallocating vector<wstring> and vector<wchar_t*>