1

次のサンプルコードがあります。グローバルポインタでローカル変数のアドレスを取得し、サブ関数でその内容を変更することが有効かどうかを知りたいだけです。次のプログラムは、変数aの値を正しく変更します。そのような練習は何か問題を引き起こす可能性がありますか?

#include <iostream>
#include <vector>

using namespace std;

vector<int*> va;

void func()
{
   int b ;
   b = 10;
   int * c = va[0];
   cout << "VALUE OF C=" << *c << endl;
   *c = 20;
   cout << "VALUE OF C=" << *c << endl;


}
int main()
{
     int a; 
     a = 1;
     va.push_back(&a);

     func();

     cout << "VALUE IS= " << a << endl;

     return 0;
}
4

3 に答える 3

2

が範囲外になったva[0]後に逆参照しようとしない限り、これは問題ありません。aそうではないので、技術的にはこのコードで問題ありません。

とはいえ、コードの保守が非常に難しくなるため、このアプローチ全体はあまり良い考えではないかもしれません。

于 2012-12-16T13:05:11.217 に答える
0

プログラムが大きくなると、関数に加えた変更を忘れて、予期しない奇妙なエラーが発生する可能性があります。

于 2012-12-16T13:07:06.550 に答える
0

func()のスコープ内にあるときに呼び出す限り、コードは完全に有効ですaただし、これは適切な方法とは見なされません。検討

struct HugeStruct {
  int a;
};

std::vector<HugeStruct*> va;

void print_va()
{
  for (size_t i = 0; i < va.size(); i++)
    std::cout<<va[i].a<<' ';
  std::cout<<std:endl;
}

int main()
{
  for (int i = 0; i < 4; i++) {
    HugeStruct hs = {i};
    va.push_back(&hs);
  }

  print_va(); // oups ...
}

上記のコードには 2 つの問題があります。

  1. どうしても必要な場合を除き、グローバル変数は使用しないでください。グローバル変数はカプセル化に違反し、変数名のオーバーレイを引き起こす可能性があります。ほとんどの場合、必要に応じてそれらを関数に渡す方がはるかに簡単です。
  2. このコードのポインターのベクトルはひどく見えます。ご覧のとおり、for ループから出るとすぐにポインターが無効になることを忘れて、print_vaゴミを出力しただけです。簡単な解決策は、ポインターではなくベクターにオブジェクトを格納することです。HugeStructしかし、オブジェクトを何度もコピーしたくない場合はどうすればよいでしょうか? かなりの時間がかかる場合があります。(1 つではなく、100 万の整数のベクトルがあるとします。) 解決策の 1 つは、 s を動的intに割り当て、スマート ポインターのベクトルを使用することです。この方法では、メモリ管理とスコープについて気にする必要はありません。オブジェクトは、誰も参照しなくなるとすぐに破棄されます。HugeStructstd::vector<std::shared_ptr<HugeStruct>>
于 2012-12-16T13:36:01.770 に答える