5

構造体への二重ポインターを取り、値を割り当てる関数があります。しかし、メンバーにアクセスしようとすると、「アクセス違反の書き込み場所...」が表示されますmember1。これは私のコードです:

struct mystruct{
  unsigned int member1;
  void * data;
};

int main(){

  mystruct **foo = new mystruct *;
  bar(foo);

}

void bar(unsigned int val, mystruct ** foo)
{
    (*foo)->member1 = val;
}
4

4 に答える 4

5

新しい mystruct ポインターを作成しました。つまり、次のことを意味します。

mystructアドレスを保持するのに十分な大きさのメモリブロックが割り当てられ、それをメンバーを指すポインターを指すポインターに割り当てます。mystructこれは、要素を指していると予想されるポインターに有効なアドレスが保持されているという意味ではありません。さらに現在、有効なメモリ領域を割り当てたばかりなので、ポインターへのポインターが指している有効なアドレスさえありません。これは、有用なアドレスが格納されていることを意味しません。

したがって、あなたが望むのは次のとおりです。

有効なメモリブロックを持つポインタが別のポインタのアドレスを格納する必要があります。これは有効なメモリ領域を指しており、(おそらく有効な) がmystruct格納されています。

あなたがしていることは、別のポインターへのポインターを保存できるメモリ領域を要求していることです...などです。

だからあなたがすべきことは次のとおりです:

mystruct **foo = new mystruct *;
*foo = new mystruct;
于 2013-10-01T08:14:17.377 に答える
4

ダブルポインタを取る関数があります

それは変だ。可能であれば、単純化して参照してください。

void bar(unsigned int val, mystruct & foo) {
    foo.member1 = val;
}

mystruct foo;
bar(42, foo);

関数を制御できない場合は、ポインター トレイルの最後にオブジェクトが必要になります。

mystruct foo;
mystruct * pointless = &foo;
bar(42, &pointless);

newもちろん、本当にしたい場合は、いじることができます。しかし、それはほぼ間違いなく悪い考えです。

コードはポインターを割り当ててリークしますが、有効なオブジェクトを指すように初期化していません。そのため、逆参照すると未定義の動作が発生します。

于 2013-10-01T08:17:27.900 に答える
2

他の答えは良いアドバイスです。しかしまた、関数を制御していて、ポインターが指すオブジェクトbarに変更できるようにする必要がある場合(これがおそらく最初に二重ポインターを持っている理由です)、最もクリーンなアプローチはには次の署名を使用します。barmystruct *bar

void bar(unsigned int val, mystruct * &foo);

ポインターを参照渡しするため、コードの可読性を犠牲にすることなく、ポインターが指すオブジェクトに変更できます。たとえば、次のようになります。

int main()
{
    mystruct * foo = new mystruct;
    bar(42, foo);
}

void bar(unsigned int val, mystruct * &foo)
{ 
    foo->member1 = val;
    foo = new mystruct;
}

メモリ リークのない完全な使用シナリオは次のようになります。

int main()
{
    // allocate dynamically a mystruct whose member1 is equal to 1.
    mystruct * foo1 = new mystruct;
    mystruct * foo2 = foo1;
    foo1->member1 = 1;

    // pass by reference foo1
    bar(42, foo1);
    // here, foo1->member1 == 42 and foo2->member1 == 10

    // free memory
    delete foo1; // the one allocated in bar()
    delete foo2; // the one allocated in main()
}

void bar(unsigned int val, mystruct * &foo)
{ 
    // modify the object allocated in main()
    foo->member1 = 10;

    // allocate dynamically a mystruct, store its address in foo
    foo = new mystruct; 
    foo->member1 = val; 
}
于 2013-10-01T09:01:22.800 に答える