我的模块尝试按照以下程序的方式执行操作:子函数尝试修改结构的元素,并将其返回给通过引用传递结构的函数。
#include <iostream>
#include <vector>
using namespace std;
struct a
{
int val1;
vector<int> vec1;
};
struct a* foo();
void anotherfunc(struct a &input);
int main()
{
struct a *foo_out;
foo_out = foo();
cout<< "Foo out int val: "<< foo_out->val1<<"\n";
cout<< "Foo out vector size: "<< foo_out->vec1.size()<< "\n";
cout<< "Foo out vector value1: "<< foo_out->vec1.at(0)<< "\n";
cout<< "Foo out vector value2: "<< foo_out->vec1.at(1)<< "\n";
return 0;
}
struct a *foo()
{
struct a input;
input.val1=729;
anotherfunc(input);
return &input;
}
void anotherfunc(struct a &input)
{
input.vec1.push_back(100);
input.vec1.push_back(1000);
input.vec1.push_back(1024);
input.vec1.push_back(3452);
cout<< "Anotherfunc():input vector value1: "<< input.vec1.at(0)<< "\n";
cout<< "Anotherfunc():input vector value2: "<< input.vec1.at(1)<< "\n";
cout<< "Anotherfunc():input int val: "<< input.val1<< "\n";
}
我期望main函数包含结构(729)中的修改整数值,以及向量值(100,10000,1024和3452)。相反,main没有这些值,并且在g ++上,程序显示了一个奇怪的行为:main()显示向量内部结构中有4个元素,但在尝试打印值时,会出现段错误。
经过一番思考之后,我假设我的问题是:“结构的结构成员是通过引用传递的,仅通过值传递?”我不应该期望该向量具有通过引用传递整个结构的函数设置的值吗?请帮助。
维杰
答案 0 :(得分:10)
struct a *foo()
{
struct a input;
input.val1=729;
anotherfunc(input);
return &input;
}
您正在返回本地对象上的指针(它将在退出函数时被销毁),因此,此处存在悬空指针,并且您的程序具有未定义的行为。
答案 1 :(得分:2)
正如ForeEveR所说,您返回的指针指向的内存不再保证包含有效对象。如果您需要此行为,请在堆上分配input
,如下所示:
a * foo ()
{
a * input = new input;
input->val1 = 729;
anotherfunc (*input);
return input;
}
现在,任何调用foo
来释放此内存的人都有责任,例如
{
a * foo_out = foo();
// do stuff with foo_out
delete foo_out; foo_out = 0;
}
在某些时候你会意识到跟踪谁分配哪些对象是乏味的,当发生这种情况时,你应该查找“智能指针”。
答案 2 :(得分:0)
首先,C ++中的“结构”并没有什么神奇之处 - 你应该像对待任何其他类型一样对待它们。特别是,您无需在任何地方编写关键字struct
。
所以这里是你的代码在更惯用的C ++(也重新排序,以避免那些浪费的预先声明):
#include <iostream>
#include <vector>
using namespace std;
struct a
{
int val1;
vector<int> vec1;
};
void bar(a& input)
{
input.vec1.push_back(100);
input.vec1.push_back(1000);
input.vec1.push_back(1024);
input.vec1.push_back(3452);
cout << "bar():input vector value1: " << input.vec1.at(0) << "\n";
cout << "bar():input vector value2: " << input.vec1.at(1) << "\n";
cout << "bar():input int val: " << input.val1 << "\n";
}
a* foo()
{
a input;
input.val1=729;
bar(input);
return &input;
}
int main()
{
a* foo_out = foo();
cout << "Foo out int val: " << foo_out->val1 << "\n";
cout << "Foo out vector size: " << foo_out->vec1.size() << "\n";
cout << "Foo out vector value1: " << foo_out->vec1.at(0) << "\n";
cout << "Foo out vector value2: " << foo_out->vec1.at(1) << "\n";
}
现在,正如其他人所指出的那样,foo()
被打破,因为它返回一个指向本地对象的指针。
为什么所有的指针都在欺骗?如果您担心复制该向量,那么您可以动态分配a
对象并使用共享指针实现为您管理该内存:
void bar(shared_ptr<a> input)
{
input->vec1.push_back(100);
input->vec1.push_back(1000);
input->vec1.push_back(1024);
input->vec1.push_back(3452);
cout << "bar():input vector value1: " << input->vec1.at(0) << "\n";
cout << "bar():input vector value2: " << input->vec1.at(1) << "\n";
cout << "bar():input int val: " << input->val1 << "\n";
}
shared_ptr<a> foo()
{
shared_ptr<a> input(new a);
input->val1 = 729;
bar(input);
return input;
}
否则,只需按值传递它。