结构的结构成员是否通过引用传递,仅通过值传递?

时间:2013-05-22 11:33:25

标签: c++

我的模块尝试按照以下程序的方式执行操作:子函数尝试修改结构的元素,并将其返回给通过引用传递结构的函数。

#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个元素,但在尝试打印值时,会出现段错误。

经过一番思考之后,我假设我的问题是:“结构的结构成员是通过引用传递的,仅通过值传递?”我不应该期望该向量具有通过引用传递整个结构的函数设置的值吗?请帮助。

维杰

3 个答案:

答案 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;
}

否则,只需按值传递它。