如何解决调用静态c ++类方法时的堆栈溢出SIGSEGV
| 我一直在研究这个问题好几个小时,并尝试了各种各样的方法,但是所有结果都相同-SIGSEGV(来自gdb;根据VC调试,它是堆栈溢出...)静态类方法被调用。 罪魁祸首代码:void LEHelper::copySinglePath (std::string from_path,std::string to_path)
{
// first check if this path is a file or folder
if (!folderExists(from_path)) // is a file
{
FILE *fp = fopen(from_path.c_str(),\"rb\");
FILE *tp = fopen(to_path.c_str(),\"wb\");
if (fp && tp)
{
// read 1MB chunks from the file and copy to the new destination until finished
LEuchar bytes[1048576];
while (!feof(fp))
{
size_t read_num = fread(bytes,sizeof(LEuchar),1048576,fp);
fwrite(bytes,read_num,tp);
}
}
if (fp)
fclose(fp);
if (tp)
fclose(tp);
}
else // is a folder
{
// make a new directory at the \"to\" path to copy files into
#if defined(LE_OS_OSX)
mkdir(to_path.c_str(),S_IRWXO | S_IRWXG | S_IRWXU);
#elif defined(LE_OS_WIN)
mkdir(to_path.c_str());
#endif
// need to get all contents and recursively perform this method with correct pathing
LEArray<std::string> contents = getContentsOfDirectoryUsingFilter(from_path,LEH_DIR_BOTH);
std::string *current;
contents.initEnumerator();
while ((current = contents.nextObject()))
{
// first build the current file or folder path (and new path)
std::string current_path = from_path;
std::string new_path = to_path;
if (current->length() > 0)
{
current_path += LE_PATH_SEPARATOR + *current;
new_path += LE_PATH_SEPARATOR + *current;
}
// then copy as necessary --- this is where things go bad ---
copySinglePath(current_path,new_path);
}
}
}
调用堆栈为:
#0 00000000 0x0040db8a in _alloca() (??:??)
#1 00403888 LEHelper::copySinglePath(from_path=...,to_path=...)
#2 00403AD1 LEHelper::copySinglePath(from_path=...,to_path=...)
#3 00403C8C LEHelper::copyPath(existing_path=...,new_path=...,ow=true)
#4 00402CD3 main(argc=1,argv=0x992c10)
在我正在测试的程序中,一旦成功到达所有正确值的递归点,就调用它(我一直在用printf
检查字符串值),但是在其中调用copySinglePath()
时会失败。由于调用堆栈非常小,我很难相信这实际上是太多递归导致的堆栈溢出……但是我的理解可能是错误的。
在寻找答案的过程中,我了解到大多数分段错误都是由指针问题引起的,因此我尝试将copySinglePath()
的参数更改为指针,并使用new
在堆中分配传入的字符串(因此,我可以控制分配,等),但没有任何区别。
同样奇怪的是,这些完全相同的代码可以在OSX上完美运行。因此,我认为mingw设置可能存在某种问题,因此我已经用最新的mingw-get重新安装了它,但仍然没有什么不同。我什至想到我的Visual Studio安装文件可能会以某种方式被使用(包括在内),因此临时尝试更改其文件夹以确保该文件仍然可以编译等,因此不应该这样。 。
我现在完全不知道为什么会这样。如果有人对我可能做错了什么有任何想法,请...
预先感谢所有人
解决方法
您可能需要减小块的大小,或将它们分配在堆上。调用堆栈很小,但是堆栈包含局部变量。默认情况下,Windows堆栈只有1MB的内存,而Unix堆栈只有8MB。从该堆栈中分配一个1MB的阵列会立即溢出。您需要更改链接器设置以允许更大的堆栈大小。
, 此变量:
LEuchar bytes[1048576];
在堆栈上,并且很大,这导致堆栈溢出。使用全局变量或动态分配的变量,问题将消失。
, 罗布规则#47:在可以使用向量的情况下,请勿使用数组:
// read 1MB chunks from the file and copy to the new destination until finished
std::vector<LEuchar> bytes(1048576);
while (!feof(fp))
{
size_t read_num = fread(&bytes[0],sizeof(LEuchar),bytes.size(),fp);
fwrite(&bytes[0],read_num,tp);
}
正如其他人所指出的那样,问题是LEuchar的1M分配了过多的堆栈。使用向量会将分配转移到免费商店。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。