0

私は C プログラミングが初めてで、助けてもらいたいと思っています。

私はこの構造体を持っています:

typedef struct house
{
   int numOfRooms;
   char* houseName;
}HOUSE,*pHOUSE;

HOUSEへのポインターを取得し、メモリ内の別の場所にある同じHOUSEへの新しいポインターを返す関数を作成したい-目的は、両方を変更せずに1つのポインターを変更できるようにすることです:私はより明確にしようとします:

pHOUSE duplicate_house(pHOUSE house)
{
  pHOUSE newh = (pHOUSE)calloc(1,sizeof(HOUSE));
  newh = house 
 //I get here a pointer that points on the same house.. so If I change for exmample:
 //  newh->numOfRooms = 9 - > both will change and I don't want it to happen!


}

memcpy_s を使用できることを読みましたが、構造体内に整数しかない場合は簡単です。ここには char * があるため、char * houseName個別にコピーする必要があることを意味しますか? 私に何ができる?のような乗算型を持つオブジェクトをコピーするにはどうすればよいchar *ですか? そしてもし私が配列を持っていたら?私は何ができますか?

typedef struct house
{
    int numOfRooms;
     char* houseName;
     struct house *houses[10];
}HOUSE,*pHOUSE;

どうすればそれをコピーできますか?

ありがとうございます!

4

1 に答える 1

2

構造と、構造によって管理されるすべてのメモリの両方をコピーする必要があります。そのようです:

pHOUSE copy(pHOUSE house)
{
    pHOUSE newHouse = malloc(sizeof *newHouse);      // allocate

    if (pHOUSE)
    {
        memcpy(newHouse, house, sizeof *newHouse);   // or "*newHouse = *house;"
        size_t const len = strlen(house->houseName);
        newHouse->houseName = malloc(len + 1);

        if (!newHouse->houseName) { free newHouse; return NULL; }

        strncpy(newHouse->houseName, house->houseName, len + 1);
    }
    return pHOUSE;
}

ご覧のとおり、2 つの割り当てによるエラー処理はすでに非常に面倒になっています。複数の内部割り当てがある場合、正気を保つ唯一の方法は、gotos を体系的に使用して適切なクリーンアップ ポイントを作成することです。


最後のポイントを説明する例:

struct FooLish
{
    char * p1;
    char * p2;
    char * p3;
};

struct FooLish * copy(struct FooLish const * oldFoo)
{
    struct FooLish * newFoo = malloc(sizeof *newFoo);
    if (!newFoo) { goto end0; }

    {
        size_t const len = strlen(oldFoo->p1);
        newFoo->p1 = malloc(strlen(len + 1);
        if (!newFoo->p1) { goto end1; }
        strncpy(newFoo->p1, oldFoo->p1, len + 1);
    }
    {
        size_t const len = strlen(oldFoo->p2);
        newFoo->p2 = malloc(strlen(len + 1);
        if (!newFoo->p2) { goto end2; }
        strncpy(newFoo->p2, oldFoo->p2, len + 1);
    }
    {
        size_t const len = strlen(oldFoo->p3);
        newFoo->p3 = malloc(strlen(len + 1);
        if (!newFoo->p3) { goto end3; }
        strncpy(newFoo->p3, oldFoo->p3, len + 1);
    }

    return newFoo;

end3:
   free(newFoo->p2);
end2:
   free(newFoo->p1);
end1:
   free(newFoo);
end0:
    return NULL;
}
于 2012-08-05T12:33:06.583 に答える