0

私は100%機能し、維持する一般的なリストを持っています:

/**
 * Generic List Container
 *
 * Implements a list container type.
 * The list his an internal iterator for external use. For all functions
 * where the state of the iterator after calling that function is not stated,
 * it is undefined. That is you cannot assume anything about it.
 *
 * The following functions are available:
 *
 *   listCreate               - Creates a new empty list
 *   listDestroy              - Deletes an existing list and frees all resources
 *   listCopy                 - Copies an existing list
 *   listGetSize              - Returns the size of a given list
 *   listFirst                - Sets the internal iterator to the first element
 *                              in the list, and returns it.
 *   listInsertFirst          - Inserts an element in the beginning of the list
 *   listInsertLast           - Inserts an element in the end of the list
 *   listInsertBeforeCurrent  - Inserts an element right before the place of
 *                              internal iterator
 *   listInsertAfterCurrent   - Inserts an element right after the place of the
 *                              internal iterator
 *   listRemoveCurrent        - Removes the element pointed by the internal
 *                              iterator
 *   listGetCurrent           - Return the current element (pointed by the 
 *                              internal iterator)
 *   listGetFirst             - Sets the internal iterator (also called current 
 *                              element) to be the first element in the list and 
 *                              return it.
 *   listGetNext              - Advances the list's iterator to the next element 
 *                              and return it 
 *   listSort                 - Sorts the list according to a given criteria
 *   listFilter               - Creates a copy of an existing list, filtered by
 *                              a boolean predicate
 *   listClear            - Clears all the data from the list
 */

そして私は提供します

  /** Element data type for list container */
typedef void* ListElement;

/** Type of function for copying an element of the list */
typedef ListElement (*CopyListElement)(ListElement);

/** Type of function for deallocating an element of the list */
typedef void (*FreeListElement)(ListElement);

List listCreate(CopyListElement copyElement, FreeListElement freeElement);

ここで、このリストを使用して、データ自体ではなく、データへのポインターを保持したいと考えています。たとえば、タイプから構造体のリストが必要です

  struct CASH_element {
        int id;
        int passengers;
        int unpaidPassengers;
        bool reset;
        int profit;
    } Cash;

    struct Transportation_element {
        List cashes; //list of cashes
        int travels;
        int profit;
    };

だから私が使用する輸送タイプを作成するとき:

    Transportation* systemToAdd;
    systemToAdd->cashes = listCreate(cashCopy, DestroyCash);
    /* MORE CODE*/ 

さて、興味深い関数は copyElement 関数です。

  void* cashCopy(void* cashCopy) {
    Cash* toCopy = (Cash*) cashCopy;
    if (toCopy == NULL) {
        return NULL;
    }

    Cash* toAdd =  (Cash*) malloc(sizeof(*toAdd));
    if (toAdd == NULL) {
        return NULL;
    }

    toAdd->id = toCopy->id;
    toAdd->passengers=toCopy->passengers;
    toAdd->unpaidPassengers = toCopy->unpaidPassengers;
    toAdd->reset=toCopy->reset;
    toAdd->unpaidPassengers=toCopy->unpaidPassengers;
    toAdd->profit=toCopy->profit;

    return  (Cash*)  toAdd;;

明らかに、これはキャッシュとそのすべてのデータを値でコピーし、キャッシュを個別に更新すると、リストノードは更新されません。更新してほしいです。ポインターを使用する必要があると思います。関数を変更しようとしましたが、失敗します:

  void* cashCopy(void* cashCopy) {

        return  (Cash*)&cashCopy;
   }

   and adding is straightforward:
     TransportationStatus trAddCash(Transportation* system, Cash c) {
        if (system == NULL) {
            return TR_FAIL;
        }
    Cash* cash=&c;
    if (LIST_SUCCESS != listInsertLast(system->cashes, cash)) {
        return TR_FAIL;
    }

    return TR_SUCCESS;

   }

私が働きたいコードサンプルがあります:

 cs1 = cashCreate(&c1, 123);
    Transportation trans1;
        TransportationStatus tr1;
    tr1=trCreate(&trans1);
    ASSERT_TEST(tr1==TR_SUCCESS);

    cs1 = cashTravel(&c1, &rq1, 660, "09/08/2011-02:51"); //THE FIRST TRAVEL
    tr1=trAddCash(&trans1,c1); //ADD THE CASH TO THE TRANSPORTATION STRUCT
    ASSERT_TEST(tr1==TR_SUCCESS);
    tr1=getTotalTravels(trans1, &result);
    ASSERT_TEST(result==1); //THAT'S OKAY BECAUSE TRAVEL BEFORE COPYING
    cs1 = cashTravel(&c1, &rq1, 660, "13/08/2011-02:51"); //THE SECOND TRAVEL
   tr1=getTotalTravels(trans1, &result);
   ASSERT_TEST(result==2); //FAIL!!!!
      cashTravel(listGetFirst(trans1.cashes),  &rq1, 660, "13/08/2010-02:51"); //TRAVEL WITH THE LIST   NODE
        tr1=getTotalTravels(trans1, &result);
  ASSERT_TEST(result==2); //SUCCESS!!!!

基本的に、ノードを個別に更新できるようにコピー機能を変更したいと思います

4

1 に答える 1

1

コードは「機能」しますが、めちゃくちゃ複雑です。ここで、「機能する」ことがコードの主な長所ではないことに気づきました。要件が変更されたときにコードを変更したり、新しいコードを作成したりできるように、十分に単純なものが必要です。

このコードを完全に破棄し、学習した内容を使用して、ポインターを保持するように簡単に変更できる新しいリストモジュールを作成します。

ヒント:malloc誰が責任を負っているのか、そしてfreeそれらの指針をどのようにして知ることができますか?

于 2012-08-13T01:00:14.960 に答える