[英]Stack overflow (SIGSEGV) when calling static c++ class method
我一直在研究这个问题几个小时并尝试了各种各样的事情,但一切都得到了相同的结果 - 一个 SIGSEGV(来自 gdb;根据 VC 调试,它是一个堆栈溢出......)在 ZA81259CEF8E959C624DF1D456E5D3292ZCABB4F2A14FBCDC42被调用。
罪魁祸首代码:
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, sizeof(LEuchar), 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()
的 arguments 更改为指针,用new
分配堆上传入的字符串(所以我可以控制分配等),但这没有任何区别。
同样奇怪的是,这个完全相同的代码可以在 OSX 上完美运行。 因此,我认为我的 mingw 设置可能有什么问题,所以我用最新的 mingw-get 重新安装了它,但仍然没有什么不同。 我什至认为我的 Visual Studio 安装文件可能会以某种方式被使用(包括在内),所以暂时更改了他们的文件夹以确保它仍然编译等,所以不应该是它......
我现在完全不知道为什么会这样。 如果有人对我可能做错了什么有任何想法,请...
提前感谢大家
这个变量:
LEuchar bytes[1048576];
位于堆栈上并且非常大,导致堆栈溢出。 使用全局变量或动态分配的变量,问题将 go 消失。
您可能需要降低块的大小,或者在堆上分配它们。 调用堆栈非常小,但堆栈包含局部变量。 默认情况下,Windows 堆栈距离 memory 仅 1MB,而 Unix 堆栈为 8MB。 从这个堆栈中分配一个 1MB 的数组会立即溢出。 您需要更改 linker 设置以允许更大的堆栈大小。
Rob 的规则 #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], sizeof(LEuchar), read_num, tp);
}
正如其他人指出的那样,问题在于 LEuchar 的 1M 分配了太多堆栈。 使用向量将该分配转移到空闲存储区。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.