2013-05-22 107 views
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()表明vector結構中有4個元素,但是當試圖打印值時,segfaults。

經過一番思考,我假設我的問題是:「結構的結構成員是否通過引用傳遞,僅通過值傳遞?」我不應該期望該向量具有通過引用傳遞整個結構的函數設置的值嗎?請幫助。

維傑

+0

你似乎在處理「結構」,就好像你還在寫C一樣。停止在每個地方寫'struct'; 'a'本身就是一種類型。 –

回答

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

您是本地對象(其出口會破壞從功能)返回指針,所以,這裏有懸擺指針和你的程序未定義的行爲。

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

在某些時候你會意識到跟蹤誰分配哪些對象是乏味的,當發生這種情況時,你應該查找「智能指針」。

+0

或者更好的是,返回一個值並避免所有這些與動態內存相關的問題。 –

+0

那麼,如果列表很大... –

+0

我不想開始討論過早優化等。;從他的帖子看來,他似乎在學習指針和引用,所以我堅持這一點。 –

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

否則,只是通過它周圍的值。