函数调用后正在解除分配的变量 我是C++初学者,遇到了一个问题。请看下面我的代码。内联注释中描述了该问题 #include<iostream> #include<tuple> #include<vector> // #include "test.hpp" using namespace std; vector<string*> test(); int main() { vector<string*> ret = test(); cout << ret.back() << endl; //Outputs: Memory of String str cout << *ret.back() << endl; //Outputs: random undefined behavior //I want this to output "s" } vector<string*> test() { vector<string*> ret; string str = "t"; ret.push_back(&str); cout << ret.back() << endl; //Outputs: Memory of String str cout << *ret.back() << endl; //Outputs: "t" str[0] = 's'; cout << ret.back() << endl; //Outputs: Memory of String str cout << *ret.back() << endl; //Outputs: "s" return ret; } #包括 #包括 #包括 //#包括“test.hpp” 使用名称空间std; 向量测试(); int main(){ 向量ret=test(); cout
您正在向后推一个局部变量的地址。当该变量超出范围时,该内存地址将被释放 您可以使用unique_ptr或shared_ptr,如下所示:函数调用后正在解除分配的变量 我是C++初学者,遇到了一个问题。请看下面我的代码。内联注释中描述了该问题 #include<iostream> #include<tuple> #include<vector> // #include "test.hpp" using namespace std; vector<string*> test(); int main() { vector<string*> ret = test(); cout << ret.back() << endl; //Outputs: Memory of String str cout << *ret.back() << endl; //Outputs: random undefined behavior //I want this to output "s" } vector<string*> test() { vector<string*> ret; string str = "t"; ret.push_back(&str); cout << ret.back() << endl; //Outputs: Memory of String str cout << *ret.back() << endl; //Outputs: "t" str[0] = 's'; cout << ret.back() << endl; //Outputs: Memory of String str cout << *ret.back() << endl; //Outputs: "s" return ret; } #包括 #包括 #包括 //#包括“test.hpp” 使用名称空间std; 向量测试(); int main(){ 向量ret=test(); cout,c++,pointers,C++,Pointers,您正在向后推一个局部变量的地址。当该变量超出范围时,该内存地址将被释放 您可以使用unique_ptr或shared_ptr,如下所示: #include<iostream> #include<tuple> #include<vector> #include<memory> // #include "test.hpp" using namespace std; vector<std::shared_ptr<string>>
#include<iostream>
#include<tuple>
#include<vector>
#include<memory>
// #include "test.hpp"
using namespace std;
vector<std::shared_ptr<string>> test();
int main() {
vector<std::shared_ptr<string>> ret = test();
cout << ret.back() << endl; //Outputs: Memory of String str
cout << *(ret.back()) << endl; //Outputs: "t"
}
vector<std::shared_ptr<string>> test() {
vector<std::shared_ptr<string>> ret;
const auto str = std::make_shared<string>("t");
ret.push_back(str);
cout << ret.back() << endl; //Outputs: Memory of String str
cout << *(ret.back()) << endl; //Outputs: "t"
return ret;
}
#包括
#包括
#包括
#包括
//#包括“test.hpp”
使用名称空间std;
向量测试();
int main(){
向量ret=test();
cout当创建对象的作用域离开时,使用自动生存期声明的对象总是不存在
如果希望对象在创建时所处的范围之外继续存在,则必须使用(直接或间接)创建具有动态生存期的对象记住,C++没有垃圾收集器,所以对于<代码>新的< /CUDE的每一次使用,你必须在完成代码时使用<代码>删除<代码>。最好的方法是使用某种形式的智能指针,像(或取决于你的确切情况):
停止使用指针。它们在C++中有位置,但不在所发布的代码中。
具体问题是:
string str = "t";
ret.push_back(&str);
您正在存储指向函数本地std::string
对象的指针。在函数结束时,std::string
超出范围并被销毁,留下悬空指针和未定义的行为
将vector-ret;
更改为vector-ret;
。存储对象而不是指针,值语义更易于推理。标准库容器和字符串的设计目的是做正确的事情,并使所有这些都变得简单。是否要更改此项:
string str = "t";
ret.push_back(&str);
为此:
string* str = new string("t");
ret.push_back(str);
问题是,在最初的示例中,当您退出test()
时,字符串会被破坏,这意味着它的内存地址现在不指向任何内容。为了避免这种情况,您需要使用指针在堆上分配str
,以便退出test()
后不会清理内存
请记住,无论何时只要在C++中手动分配内存,就必须重新分配内存以避免内存泄漏:
for (string* i : ret) {
delete i;
}
在字符串被销毁后,您不能使用它。请改用vector
。然后导致内存泄漏。这可能值得一提。我不同意这个解决方案。您只是在教他们如何泄漏内存或陷入手动内存管理的泥潭。@blastfull我更新了答案来解释这一点。我仍然感觉不太好关于此。使用手动内存管理,您负责删除对象一次又一次,在正确的时间。它让你可以在释放bug后进行双重删除和使用。注意:我不是一个消极的投票者,只是一个温和的批评者。@可能是这样,但其他答案已经涵盖了问题的动态角度。OP在他的问题中使用手动内存分配,并提到他希望能够看到strin中的变化g反映在向量中,这可以通过指针来完成,因此在回答中完全可以解决这一问题。您可以添加如何在向量中创建对对象的引用,以使“以后能够在函数中再次修改对象”部件清理器。如果执行此操作,则无法再修改添加的字符串。str[0]='s';
不再有效。我的最终目标是对任何通用对象执行此操作。我只是使用字符串来简化代码以显示问题。@我不知道您的真实代码是什么样子,但这听起来很牵强。使用std::vector
绝对不会阻止您修改向量的元素。确实如此是的,我很快写了一些东西来说明向量v;string test=“t”v.push_back(test);test[0]='s';cout@JustinWang您的问题不清楚您是否想要一个指向存在于向量之外的对象的引用向量。您的问题是对象生命周期,而不是向量。您可以通过动态分配和智能指针来解决这一问题。将原始指针保存在向量中会产生谁拥有对象以及谁释放对象的m的问题埃默里,祝你好运。
string* str = new string("t");
ret.push_back(str);
for (string* i : ret) {
delete i;
}