首先说下什么时候数据存在堆 什么时候存在栈
像在函数内定义的变量类似int a = 1; 或数组 char[1024]={0};
这种是在函数的栈空间内分配空间的,在退出函数的时候,栈空间会自动回收
像new申请的变量,是在堆空间中申请的,需要你手工回收。
当然也有类似智能指针或gc这类的东西来帮你做回收的,不过干的事都是一样,只是区别在于你干还是编译器帮你干。
栈溢出问题
在栈中不能申请很大的变量,否则会栈溢出,申请不成功,对于大的变量建议你new
下面是遇到的一个问题
bool FtpLib::DownLoadFileThread()
{
g_receiving = true;
g_FileSize = 0;
g_RecvSize = 0;
mhHost = InternetOpen(_T("ftp"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if(!mhHost){
g_receiving = false;
return false;
}
mhConnect = InternetConnect(mhHost,Server,Port,UserName,PassWord,
INTERNET_SERVICE_FTP, 0, 0);
if(!mhConnect)
{
InternetCloseHandle(mhHost);
g_receiving = false;
return false;
}
mfserver = FtpOpenFile(mhConnect,ServerFile,GENERIC_READ,FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_TRANSFER_BINARY ,NULL);
if(!mfserver){
InternetCloseHandle(mhConnect);
InternetCloseHandle(mhHost);
g_receiving = false;
return false;
}
DWORD dw;
g_FileSize = ::FtpGetFileSize(mfserver,&dw);
g_RecvSize = 0;
mflocal = _wfopen(LoaclFile,L"wb");
if(!mflocal){
printf("FILE *flocal = _wfopen ,f/n");
InternetCloseHandle(mfserver);
InternetCloseHandle(mhConnect);
InternetCloseHandle(mhHost);
g_receiving = false;
return false;
}
unsigned long bytelen = 50*1024;//1024x1024;
unsigned char bytes[50*1024] = {0}; //这里千万不要如此申请 字符串 尽量用指针申请
//unsigned char *bytes = new unsigned char[bytelen];
unsigned long getlen = 0;
while(::InternetReadFile(mfserver,bytes,bytelen,&getlen))
{
g_RecvSize += getlen;
fwrite(bytes,1,getlen,mflocal);
if(getlen < bytelen){
break;
}
}
//delete[] bytes;
if(mflocal)
fclose(mflocal);
mflocal = NULL;
if(mfserver)
InternetCloseHandle(mfserver);
mfserver = NULL;
if(mhConnect)
InternetCloseHandle(mhConnect);
mhConnect = NULL;
if(mhHost)
InternetCloseHandle(mhHost);
mhHost = NULL;
g_receiving = false;
return true;
}
在执行
mhConnect = InternetConnect(mhHost,Server,Port,UserName,PassWord,
INTERNET_SERVICE_FTP, 0, 0);
的时候,弹出了应用程序致命错误的提示。
而将红色字部分去掉,改成绿色字部分,则没有问题。
这说明unsigned char bytes[50*1024] = {0};导致了栈溢出
当时跟到这发现出错,想破了头都想不明白,后来把之前的程序拿出来一比,才发现问题的缘由,于是才知道原因。
切记切记 以后申请数组 一定要用new 在堆中申请。