Run-Time Check Failure #2 - Stack around the variable 'size' was corrupted.

此处的size是一个variable,即,变量,下面将出错的代码贴出

// 将文件读入内存,返回内存指针与文件的大小
bool GetFileToMemory(
		const char *pFilename,
		char* &pContent,
		int &size)
{
	FILE *pFile = NULL;
	if ((pFile = fopen(pFilename, "r")) == NULL)
	{
		printf("打开文件%s失败! \r\n", pFilename);
		return false;
	}

	// 获取文件大小
	fseek(pFile, 0, SEEK_END);
	fgetpos(pFile, (fpos_t*)&size);

	// 获取文件内容
	if (pContent == NULL)
	{
		pContent = new char[size];
	}
	memset(pContent, 0, size);
	fread(pContent, 1, size, pFile);
	fclose(pFile);

	return true;
}

void test4()
{
	const char *pFilename = "temp.txt";
	char *pContent = NULL;
	int size;
	GetFileToMemory(pFilename, pContent, size);

	if (pContent != NULL)
	{
		delete [] pContent;
	}
}

void main()
{
	test4();

	system("pause");
}
在网上查了一下关于这个错误,大概的解释就是:变量的栈信息被改变了,这里有一个参考文章说的蛮好的:
比如说我这里的size这个变量,它的大小在32位机上面是4个字节,而每个变量的前面和后面是有几个字节存放的是这个变量的信息,如前面一个字节和后面一个字节存放的是这个变量的信息(具体是什么信息我不记得了,就记得变量在运行时实际中所占的字节不是你认为的那么多,而是包含了这个变量的相关信息,哪位大侠知道的话,麻烦给我一下连接,我也好学习一下这方面的内容<^^>),这样一来,如果你一不小心改变这个部分的信息,就有可能引起程序的崩溃,就像我上面的截图那样
 
下面说一下,我贴的这段代码错误所在,我想看完上面的那个简要的分析,应该就知道是哪里出问题了吧,没错,就是size这个变量,在test4()函数中,它被定义成了int类型,在32位机上面它占有4个字节,以“引用”的方式传入到GetFileToMemory()这个函数中,而在这个函数中有一个这样的调用
fgetpos(pFile, (fpos_t*)&size);
即,把文件的大小写到size中,fgetpos()要求传入是一个fpos_t*的类型,而size是int类型,此处将int取了地址,并强制将地址转换为fpos_t这个类型,看一下fpos_t这个类型的原型:typedef __int64 fpos_t; 看到了吧,它是__int64类型的,即,它在32位机上面占有8个字节!!! OK了,把四个字节的地址传给操作8个字节的函数,它就操作了另外的四个字节,这样,原来size的"变量信息栈"所占有的字节就被破坏了,所以在出test()这个函数的时候就出现了上面的那个对话框!
只要做一下修改,像这样:
 fpos_t outSize = 0;
 fgetpos(pFile, (fpos_t*)&outSize);
 size = (int)outSize;
这样就OK了,在这个地方建议存放文件大小的变量就使用fpos_t这个类型来定义,这样就不会出现上面的那个麻烦了,Win32 API 里面也有说到,早期获取文件大小的API是会有错误的,因为提取大文件的时候,一个DWORD是不够存放文件的大小的(sizeof(DWORD) == sizeof(int) 在32位机上面),WIN32 API也是使用两个DWORD来存放文件的大小的,所以......,你懂的......
 
关于这个错误,具体代码要做具体分析,我的分析就到这里!
posted @ 2011-09-27 21:10  莫压枯枯地  阅读(7728)  评论(1编辑  收藏  举报