当前位置:C++技术网 > 资讯 > BROWSEINFO结构体中的参数调用出错引发0xC0000005错误

BROWSEINFO结构体中的参数调用出错引发0xC0000005错误

更新时间:2015-12-23 21:28:36浏览次数:1+次

这是我们写程序时最不想看到的事了,这个错误可真是天坑的。这是新手写代码时老是遇到的问题,当然前提是你经常写代码(自恋下)。下面说正事:
今天写代码,遇到了这个问题,想想还是彻底解决吧,以前遇到这样的问题都是算了,今天彻底研究下。下面我先介绍下0xC0000005这种错误的函数,看到这串数字自己都不知道哪里出错了,连什么意思都不知道。首先,这是十六进制表示的地址,这是你要知道。通常出现这样的错误就是内存地址出错。对于这样的错误就是变量没有初始化,从你出错的那行代码开始向上找,既然是内存的问题,你调用Debug窗口的"调用堆栈“窗口,崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。在这里面,找内存的错误,看看有哪些内存错误。
其次,最最死的办法就是自己找。既然知道这是变量的初始化问题,最常见的就是"野指针",也就是没有初始化的指针。
下面,就是我遇到的问题,先上代码:

/////代码1
void CFileRenameDlg::OnBtBrowse() 
{
	BROWSEINFO browInfo;
	ITEMIDLIST itemList;
	memset(&browInfo, 0, sizeof(BROWSEINFO));
	memset(&itemList, 0, sizeof(ITEMIDLIST));
	browInfo.hwndOwner = m_hWnd;
	browInfo.pidlRoot = &itemList;
	browInfo.pszDisplayName = "浏览";
	browInfo.lpszTitle = "请选择目录";
	LPITEMIDLIST  pItemList = SHBrowseForFolder(&browInfo);///错误源
	char szDir[256] = {0};
	SHGetPathFromIDList(pItemList, szDir);
	m_FileDir.SetWindowText(szDir);
}
然后我就开始找,各种断点,变量调试,还是失败。之后,我想到前几天,一个漂亮的学姐问我的问题——怎么调用文件夹对话框,当时我也不知道,然后特意研究了一下。写篇文章《文件夹对话框的创建》,今天这个也是需要调用文件夹对话框,然后,我就把之前的那个文件夹对话框的代码,给复制过来了,一运行,好家伙!还真可以。我们先看下之前的代码:
/////代码2
void C重命名Dlg::OnBnClickedButton1()/////选择文件夹
{
	// TODO: 在此添加控件通知处理程序代码
	TCHAR szPath[1000];
	CString str;
	ZeroMemory(szPath, sizeof(szPath));
	BROWSEINFO bi;
	bi.hwndOwner = this->GetSafeHwnd();
	bi.pidlRoot = NULL;
	bi.pszDisplayName = szPath;
	bi.lpszTitle = L"请选择文件夹:";
	bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
	bi.lpfn = BrowseCallBackProc;
	bi.lParam = (LPARAM)_TEXT("桌面:\\");
	bi.iImage = 0;
	LPITEMIDLIST lp = SHBrowseForFolder(&bi);
	if (lp && SHGetPathFromIDList(lp, szPath))
	{
		str.Format(L"选择的目录为 %s", szPath);
		//AfxMessageBox(str);
	}
	else
	{
		AfxMessageBox(L"无效的目录,请重新选择");
		return;
	}
	m_FileDir.SetWindowTextW(szPath);
}

然后我看着这个代码,就在想,bi.lpszTitle 是:

那么pszDisplayName是什么呢?我就查了下:
pszDisplayName:用来保存用户选中的目录字符串的内存地址。该缓冲区的大小缺省是定义的MAX_PATH常量宏。
也就是这是我们选择的文件的存储地址,MAX_PATH是256,在VS编译器中的有定义#define MAX_PATH 256。说到这里你也应该懂了。代码1中的pszDisplayName的值是什么?他就是一个变量,但我们需要的是一个地址,也就是一个字符串的地址。代码1中的值不符合我们的要求,编译器就报错咯