Malloc()は、構造体の配列ではなく、単一の構造体用のスペースを作成します

arrays iphone malloc objective-c struct
Malloc()は、構造体の配列ではなく、単一の構造体用のスペースを作成します

私は一日中この問題に頭を打ち続けてきました。手伝ってくれる人にはとても感謝しています。

これが取引です-malloc()を使用して動的なC配列を作成しようとしています。 この配列はCGPoint構造体を保持します。これは、配列の構築直後に構築と割り当てを開始します。 これがコードです:

CGPoint* tempVertices = malloc(sizeof(CGPoint) * 4);  //defining a collision frame
tempVertices[0] = CGPointMake(37, 46);
tempVertices[1] = CGPointMake(69, 40);
tempVertices[2] = CGPointMake(48, 6);
tempVertices[3] = CGPointMake(17, 10);

//Then I pass the pointer to my array off to a setter...
[self setVertices: tempVertices];

ただし、tempVerticesが作成されると、1つのCGPointのスペースしか取得できないようです。

int test1 = sizeof(CGPoint);        // 8
int test2 = sizeof(tempVertices);   // 4
int test3 = sizeof(*tempVertices);  // 8

XCodeデバッガーをステップスルーすると、「tempVertices」が「CGPoint」へのポインターであることを示します。 「tempVertices [0]」を設定すると、「tempVertices」が指す「CGPoint」がその値を受け取り、それがデバッガーに反映されます。 他の3つのスロットはどこに行きましたか? 「tempVertices」は、配列ではなく単一の「CGPoint」を指しているようです。 配列が欲しい。

何がおかしいのですか? C ++や他のオブジェクトを使用してこれを修正する他の方法があることは知っていますが、可能であればCに固執したいと思います。

前もって感謝します!

” ” ‘

更新日:

zpasternackに答えるために、 `setVertices:`はカスタム記述セッターです。 そして、どのように/入ってくる配列の大きさを知っているのかわかりません。 私はまっすぐなCのものをより良く理解しようとしているので、引数として動的なC配列を渡す適切な方法に関する洞察/説明は大歓迎です。 セッターは次のようになります。

- (void) setVertices:(CGPoint*) val {
    _vertices = val;    //_vertices is a member variable of the type CGPoint*
    //...calculate a centroid, other stuff...
}

必要に応じて、CGValuesをNSValueオブジェクトでラップし、代わりにNSArrayを使用できますが、プレーンol ‘Cでそれを行う正しい方法を知りたいと思います。

コメントしてくれたみんなに感謝-あなたたちは素晴らしいです:)

  2  0


ベストアンサー

32ビットマシンでは、期待どおりの結果が得られます。 sizeof(tempVertices)はポインターのサイズであり、sizeof(* tempVerices)はCGPint(おそらく2つのint)のサイズを示します。 sizeof()を使用して、割り当てられた配列のサイズを取得することはできません。 値はrun-rimeでのみ認識され、sizeof()はコンパイル時の演算子です。

4


mallocは、4つのGCPoint構造体に十分なスペースを割り当て、割り当てられたスペースへのポインターを返します。

最初はtempVertices + 0です。 tempVertices [0]です。

2番目はtempVertices + 1です。 tempVertices [1]です。

3番目はtempVertices + 2です。 tempVertices [2]です。

4番目はtempVertices + 3です。 tempVertices [3]です。

1


OK、編集後、何が起こっているのかわかります。 そのコードは、あなたが書いたとおりに、正常に動作するはずです。 XcodeはこれらのCGPointの値を表示しません。これは、それが配列であることを知らず、ただ1つのCGPointへのポインターだからです。 しかし、それはそこにあります。 `setVertices:`を呼び出した直後にブレークポイントを設定します。 gdbプロンプトで、これらの値の一部を出力します。

(gdb) print _vertices[1]
$2 = {
  x = 69,
  y = 40
}
(gdb) print _vertices[3]
$3 = {
  x = 17,
  y = 10
}

正しいですか?

ここに問題がないと言っているわけではありません。 一つには、 `setVertices:`はそのメモリをリークしています。 「tempVertices」にメモリを割り当て、そのポインタを保持しますが、どこでも解放しません。 次回 `setVertices:`を呼び出すと、リークが発生します。

大きな問題は、メモリを割り当てたコードを除いて、その配列にあるCGPointの数を誰も知らないことです。 常に4 CGPointになりますか? 誰かが `_vertices [5]`または `_vertices [27]`にアクセスするとどうなりますか? 悪いことは、あなたがそれらに多くのスペースを割り当てなかった場合です。

これが単純なC配列であるという要件はありますか? 同様に、これらのポイントはOpenGLまたはcocos2dなどに渡されますか? そうでない場合は、何らかの配列クラスを使用することを検討してください。 これらは、保存しているNSObjectから派生したオブジェクトではないため、NSArrayは使用できません。 buncha C ++でのドラッグを気にしない場合は、 `std

vector`を使用できます。 私はおそらくそうしないでしょう。

C配列に固執するように設定されている場合は、おそらく、インターフェイスのエラーが発生しにくいようにするためにいくつかの作業を行う必要があります。 前述したように、配列のサイズを追跡する必要があります。 おそらく、パラメータをsetVerticesに追加できます。配列が保持するCGPointsの数を表します。 次に、 `_vertices`にアクセスするコードの他の部分は、配列の最後から外れていないことを確認するためにそれをチェックできます。 そして、前述したように、ポインターを再割り当てする前に、そのメモリーを必ず解放してください。

ポインターをいじるのは危険です。 慎重に踏み、そこにドラゴンがいます。

1


実行時に割り当てられた配列のサイズを決定するために `sizeof()`を使用しません。

配列に新しい `CGPoint`オブジェクトを割り当てるのに実際に問題がありましたか? `CGPointMake()`は独自の割り当てを実行しますか?

0


タイトルとURLをコピーしました