gpt4 book ai didi

std::string 析构函数上的 c++ 段错误,仅当传递变量时

转载 作者:行者123 更新时间:2023-11-30 04:23:28 29 4
gpt4 key购买 nike

这个问题发生在很多繁忙的函数中间,所以我将尝试用伪代码来解释这个问题,希望它足够了。我对理解潜在问题和解决它同样感兴趣,所以除了修复之外,我还希望得到解释。谢谢!

“methodOne”从另一个函数中检索 std::string xx,并将其与字符串 x1、x2 和 x3(全部来自新对象)一起发送到“methodTwo”。

bool methodOne(...) {
Object1 obj = Object1(...);
string xx = obj.someFunction(...);
methodTwo(xx, obj.getX1(), obj.getX2(), obj.getX3() );
...
return true;
}

然后“methodTwo”(在 Object2 中)将这些字符串组合成一个 vector ,并将它们传递给“methodThree”。

bool Object2::methodTwo(const string xx, const string x1, const string x2, const string x3) {
vector<string> holder; // alternate - comment out this line
holder.push_back(xx); // and this line,
// vector<string> holder(1, "test"); // alternate - uncomment this line
holder.push_back(x1);
holder.push_back(x2);
holder.push_back(x3);
...
obj3.methodThree( holder );
...
return true;
} // line 443 - where error is backtraced to

最后,'methodThree' 最终创建了几个文件,所有四个字符串都打印到其中一个。

运行程序,我从 gdb 得到一个段错误:

Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: 13 at address: 0x0000000000000000 0x00007fff8f1e3aa2 in std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::~basic_string () (gdb) where
#0 0x00007fff8f1e3aa2 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string ()
#1 0x0000000100009f18 in std::_Destroy<std::string> ()
#2 0x0000000100009f3e in std::__destroy_aux<std::string*> ()
#3 0x0000000100009f9f in std::_Destroy<std::string*> ()
#4 0x0000000100009fd7 in std::_Destroy<std::string*, std::string> ()
#5 0x0000000100060115 in std::vector<std::string, std::allocator<std::string> >::~vector (this=0x7fff5fbfd488) at stl_vector.h:271
#6 0x0000000100013b9f in Station::methodTwo (this=0x7fff5fbff110, foreFN=@0x7fff5fbfdf08, startDT=@0x7fff5fbfded8, stopDT=@0x7fff5fbfdea8, numElems=169, tCase=0x7fff5fbfe7c8) at Station.cpp:443
#7 0x0000000100002b45 in methodOne ()
#8 0x000000010000707a in main ()

在“methodTwo”中,如果我用一些随机测试字符串替换字符串“xx”,错误就会消失。所以问题必须出在 'xx' --- 这也是 'methodOne' 中唯一不是来自 Object1 obj 的字符串。

我在想一些构造函数实际上并没有复制字符串(是浅复制术语吗?)所以我尝试做一些事情,比如调用 methodTwo as

methodTwo( string(xx), obj.getX1() ...)

或者在构造 vector 时,使用类似的东西

holder.push_back( string(xx) );

但这些都不起作用。

我完全不知所措,我将不胜感激任何人的帮助/提示。我知道这很烦人,因为我没有给出可以重现问题的连贯代码,甚至没有给出实际代码 --- 但希望这足以让比我更聪明的人看到一些东西。

谢谢


新奇点:

从下面的评论来看,这听起来很可能是其他地方的实际错误,感染了堆。但是,因为 xx 仅通过 notobj 中检索来区分,所以我尝试将 xx 添加到对象中 - -- 即在之前调用的另一个方法中,变量 xx 被设置为与之前应该相同的结果值...

string Object1::someFunction(...) {
...
string val = ...;
setXX(val);
cout << getXX() << endl; // this *correctly* prints the value of xx
...
return val;
}
void Object1::setXX(string temp) { xx = string(temp); }
string Object1::getXX() { return xx; }

然后我在 methodTwo 调用中检索 xx:

methodTwo(obj.getXX(), obj.getX1() ... );

这已经阻止了错误,但是 xx 不会存储字符串!!!

obj.someFunction(...);          // this is able to set and retrieve xx
cout << obj.getXX() << endl; // prints **blank line!!**
methodTwo(obj.getXX(), obj.getX1() ...); // no more error, x1 x2 x3 are fine, xx is empty!

现在我觉得我要疯了......

最佳答案

当您在内存分配器内部崩溃时,您很少能将问题追溯到崩溃瞬间被释放(或分配)的确切内存。分配器将进行健全性检查,通常会捕获释放无效指针的尝试(未指向某些分配开始的指针、堆边界外的指针、重复释放等)。内存分配器崩溃的最常见原因是堆损坏。通常释放的 block 使用 block 前面的小结构链接到其他空闲 block 。在释放的内存上写入或超出分配的 block 写入将破坏这些指针并导致分配器崩溃。

我希望如果您的替代程序在避免初始崩溃后运行足够长的时间,无论如何最终都会发生另一次崩溃。您观察到的 xx 模式可能很简单,因为 xx 的长度与 x1..x3< 有很大不同 并因此从不同的内存池中分配。

这里有一个测试:如果你只是把 return 放在 methodThree 的顶部,程序是否仍然会崩溃?

关于std::string 析构函数上的 c++ 段错误,仅当传递变量时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13335588/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com