Reputation: 209
I have a generic list which works 100% and maintains:
/**
* 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
*/
and I provide
/** 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);
Now, I want to use this list to hold pointers to data instead of the data itself. For example, I want a list of structs from the type
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;
};
so when I create the transportation type I use:
Transportation* systemToAdd;
systemToAdd->cashes = listCreate(cashCopy, DestroyCash);
/* MORE CODE*/
Now, the interesting function is the copyElement function:
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;;
Obviously, this copies by value the Cash and all its data and once I update cash independently, the list node DOESN'T update. I want it to be updated. I guess I have to use pointers. I've tried modifiend the function but it fails:
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;
}
There is a code sample which I want to work:
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!!!!
So basically, I would like to modify my copy function so I could update the node independently
Upvotes: 0
Views: 222
Reputation: 202505
Although your code "works," it is insanely complex. Now you are discovering that "working" is not the primary virtue in code—you need to have something simple enough that when requirements change, you can change the code, or make new code.
Abandon this code entirely, and use what you have learned to make a new list module that you will easily be able to modify to hold pointers.
Hint: How will you know whose responsibility is is to malloc
and free
those pointers?
Upvotes: 1