0

次の構造体があるとします。

typedef struct plane_t Plane;
struct plane_t{
    Point p1;
    Point p2;
    Point p3;
};

typedef struct arrangement_t* Arrangement;
struct arrangement_t{
    //TODO add fields here
    int maxPlanes;
    int curPlanes;
    Plane *planes;
};

そして、私は次の機能を持っています:

Plane planeCreate(Point point1, Point point2, Point point3){

    Plane newPlane = {{point1.x, point1.y, point1.z}, {point2.x, point2.y, point2.z}, {point3.x, point3.y, point3.z}};
    return newPlane;
}

Arrangement arrangementCreate(int maxPlanes){

    if (maxPlanes < 1) return NULL;

    Arrangment newArrangment = malloc(sizeof struct arrangement_t);
    if (newArrangment == NULL) return NULL;
    newArrangment->planes = malloc(sizeof(Plane)*maxPlanes);
    if (newArrangment->planes == NULL) {
        free(newArrangment);
        return NULL;
    }

    newArrangment->maxPlanes = maxPlanes;
    newArrangment->curPlanes = 0;

    return newArrangment;
}

次の行は、配列内のすべてのセルが Plane 型のスタックを持つことを意味しますか?それとも、各セルを手動で 1 つずつ作成する必要がありますか? newArrangment->planes = malloc(sizeof(Plane)*maxPlanes);

4

2 に答える 2

2

malloc構造体の配列に十分なスペースを割り当てmaxPlanesますが、それらを初期化するのはあなた次第です。

つまり、成功すると、 を介しmallocて構造体にアクセスできるようになります 。構造体は、メモリ内で 1 つの連続したブロックとして端から端まで配置されます。newArrangement->planes[0]newArrangement->planes[maxPlanes-1]

于 2013-08-02T23:27:37.070 に答える
1

あなたのコードはおそらく(以下を参照)問題ありません(「良い」とは、機能的であり、適切に設計されていないことを意味します)。malloc(sizeof(Plane)*maxPlanes) は maxPlanes プレーンにスペースを割り当てます。各セルを割り当てる必要はありません。

セル自体は「Plane 型の構造体」ではなく、maxPlanes Plane 構造体に格納された情報を保持するのに十分な大きさのメモリ ブロックにすぎません。Plane ポインターを介してそのブロックにアクセスしているため、データは Plane 構造体として解釈されます。

おそらく、 Plane 構造体のメンバーが初期化されない(ランダムなデータが含まれる) ためであり、 Point が何であるかを示していないため、持っているものが十分かどうかを知るのに十分な情報がないためです。また、arrangement_t を使用して最終的に何をするのかを示していないため、値を初期化せずにそのままにしておいて、値を後で意味のあるものに設定していると思います。

また、コードを明確にするためにいくつかの推奨事項を作成します。

  1. Arrangement はポインターとして型定義しますが、Plane は構造体として型定義します。おそらく、アレンジメント タイプを ArrangementPtr などとして修飾して、区別して混乱を減らすことをお勧めします。

  2. わかりやすくするために、malloc の代わりに calloc を使用することを検討してください: calloc(maxPlanes, sizeof(Plane))

  3. 初期化のためにメモリをゼロにすることが許容される場合は、簡単な memset(planes, 0, sizeof(Plane)*maxPlanes) を実行できます。

  4. C を使用する特定の理由 (多数あります) がない限り、C++ (利用可能な場合は STL クラスを使用) を検討することをお勧めします。これにより、多くの作業とコード内のエラーの可能性のある原因が大幅に削減されます。 (これはまだ理想的ではないことに注意してください。これは、パブリック メンバーが不変条件を破る可能性があるためです。ただし、例として):

 

struct Plane {
    Point p1;
    Point p2;
    Point p3;
    Plane ();
    Plane (const Point &, const Point &, const Point &);
};

struct Arrangement {
    int maxPlanes;
    int curPlanes;
    std::vector<Plane> planes;
    explicit Arrangement (int maxPlanes);
};

Plane::Plane () {
}

Plane::Plane (const Point &p1, const Point &p2, const Point &p3) :
    p1(p1), p2(p2), p3(p3)
{
}

Arrangement::Arrangement (int maxPlanes) :
    maxPlanes(maxPlanes),
    curPlanes(0),
    planes(maxPlanes)
{
}

これにより、すべてのメモリ管理が処理されます。あなたの仕事は、 std::bad_alloc をキャッチしてメモリ割り当てエラーをチェックするか、必要なパラメーター検証を追加することです。

あなたのコードには他にも多くの問題があるか、問題の可能性がありますが、それはこの質問の範囲外だと思います。

于 2013-08-02T23:38:19.047 に答える