0

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

#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";

}

我期望主函数包含结构(729)中修改后的整数值,以及向量值(100,10000,1024 和 3452)。相反,main 没有这些值,并且在 g++ 上,程序显示出一种奇怪的行为:main() 显示结构内部的向量中有 4 个元素,但是在尝试打印这些值时,出现了段错误。

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

维杰

4

3 回答 3

10
struct a *foo()
{
  struct a input;
  input.val1=729;
  anotherfunc(input);  
  return &input;
}

您正在返回本地对象上的指针(它将在退出函数时被销毁),因此,这里有悬空指针并且您的程序具有未定义的行为。

于 2013-05-22T11:35:04.507 回答
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;
}

在某些时候,您会意识到跟踪谁分配了哪些对象是乏味的,当这种情况发生时,您应该查找“智能指针”。

于 2013-05-22T11:42:55.093 回答
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;
}

否则,只需按值传递它。

于 2013-05-22T11:48:53.693 回答