2011-12-08 3 views
2

私たちはスレッドやミューテックスを使ってプロジェクトをやっています。 C/C++の経験はほとんどないし、この問題はポインタに関連していると思う。基本的には、トランザクションのリストとアカウントのリストを含むClientオブジェクトがあり、それは処理メソッドに送られるpthreadにパラメータとして渡されます。PThreadsを使用したグローバルリストアクセス - ポインタの問題?

class Client{ 
public: 
    list<Transaction> transactions; 
    list<Account>* accounts; 
    Client(list<Transaction>, list<Account>); 
}; 

Client::Client(list<Transaction> a, list<Account> b){ 
transactions = a; 
accounts = &b; 
} 

extern "C" 
{ 
void* RunTransactions(void* arg) 
{ 
    Client* c = static_cast<Client*>(arg); 

    // while(!(*c).transactions.empty()){ 
     // cout << "HERE" << endl; 
    // } 

    cout << "Thread Before: "; 
    (*(*c).accounts).front().Print(); 

    (*(*c).accounts).front().balance -= 25; 
    (*(*c).accounts).front().balance -= 25; 
    (*(*c).accounts).front().balance -= 25; 

    cout << "Thread After: "; 
    (*(*c).accounts).front().Print(); 

    // list<Transaction>* trans = static_cast<list<Transaction>*>(arg); 
    // Transaction t = trans->front(); 
    // t.Print(); 

    // Test* t = static_cast<Test*>(arg); 

    // (*t).Increase(); 
    // cout << "Thread - " << t->x << endl; 

    return 0; 
} 
} 

int main(){ 

list<Account> accounts; 

cout << "Accounts: "; 
cin >> NumAccts; 

for(long i = 0; i < NumAccts; i++){ 
    long tempBalance; 
    cout << "Balance for Account " << i << ": "; 
    cin >> tempBalance; 

    accounts.push_back(Account(i, tempBalance)); 
} 

//Test Input 
pthread_t t1; 
list<Transaction> tempTrans; 
tempTrans.push_back(Transaction(0, 1, 100)); 
tempTrans.push_back(Transaction(1, 0, 50)); 
tempTrans.push_back(Transaction(2, 1, 222)); 

Client c = Client(tempTrans, accounts); 

cout << "Main Before: "; 
accounts.front().Print(); 

pthread_create(&t1, NULL, RunTransactions, &c); 

pthread_join(t1, NULL); 

cout << "Main After: "; 
accounts.front().Print(); 


return 0; 
} 

スレッドでメインに作成されたアカウントリストにアクセスするにはどうすればよいですか?現在、私はクライアントから引き出すアカウントリストを何かするたびにスレッドの変更を行いますが、結合後のメインのアカウントリストの変更は表示されません。繰り返しますが、クライアントオブジェクトやメイン、またはRunTransactionsのアカウントを通過する方法やアクセスする方法と関係がありますか?どんなアドバイスも大歓迎です!

+1

あなたの質問に無関係ですが、なぜあなたは ' - >'演算子を避けていますか? –

答えて

1
Client::Client(list<Transaction> a, list<Account> b) { 

bに渡されたリストのコピーであり、そしてほぼ確実にスタック上に渡されます。コンストラクタが返されるとすぐに、あなたのポインタはおそらく無効です。

クライアントのaccountsを実際のリストではなく実際のリストにする方がよいでしょう。ヒープ割り当てされていないもの、または他の誰かがアクセス権を持っているものへのポインタをオブジェクトに保持させることは、実際には望んでいません。そういうわけで、狂気がある。

+0

「アカウントを実際のリストにする」という意味が不明です。私がClientクラスのポインタの代わりにリストを作成したのであれば、それは単なるコピーではないので、すべての変更はmainのリストに影響しませんか? –

+0

右。このような副作用は通常は事故であり、そうでない場合でも悪い考えです。 (それは「離れたところでの行動」と呼ばれ、反パターンです。)あなたのクライアントが何かをした後にリストを望むなら、クライアントにメソッドを追加してリストを取得してください。一般に、あなたのオブジェクトは、その内部にあるものを所有する必要があります。さもなければ、呼び出し側はオブジェクトの内部状態を調べて、指定した不変条件を破ります。 – cHao

0
Client::Client(list<Transaction> a, list<Account> b){ 
    transactions = a; 
    accounts = &b; 
} 

は基本的に言っている:「そうそう、ロイ、あなたはここにこのリストを持って、右、すべてのこれらのアカウントでまあ、誰かが私にそれを電子メールで送信、あなたが見ることができるリストは、ちょうど店どこから来ましたの?リストを作成した人の名前は?私は後でそのアドレスからリストを返すことができると確信している」

ロイはクライアントのプロフィールに「Waldo」という名前を保存しています。それ以降に何が起こったのか、私たちは皆知っている。彼はクライアントが悲しいことにそれを求めたときに、リストを再び検索することは決してできませんでした。彼がリストのコピーを作っただけの場合、またはリストを作成したソースがある日消えないことを確かめた場合。

関連する問題