问题
i have a card game in C (i have to make it in C, class project). And i created a method for moving Structs from one dynamic array to another. Unfortunately the method works at first, but later when i call it in the program it starts throwing malloc() errors. Deck is a struct that contains a int size and a dynamically allocated Card *deck, and Card is a struct for holding a single card. Is there something i am missing, or that has to be defined in another way ?
void moveCard(Deck *src, Deck *dest, int n){
Card *tmpCards = NULL;
Card tmp = (*src).deck[n]; // get card to be copied
int newSize = dest->size + 1; //increase dest size by 1
tmpCards = (Card *) malloc(sizeof(Card) * newSize); // allocate new memory area
memmove(&(tmpCards[0]), &(dest->deck[0]), sizeof(Card) * (newSize - 1));
// copy all the cards from old memory area to new area
dest->deck = tmpCards; // reassign old pointer to new memory area
dest->size = newSize; // reevaluate size
dest->deck[newSize - 1] = tmp; // copy card to end of new area
tmpCards = NULL; // empty out pointer (no functionality, just for easier reading)
newSize = src->size; // reevaluate newSize
tmpCards = (Card *) malloc(sizeof(Card) * (newSize - 1));
// allocate smaller mem area by 1
memmove(&(tmpCards[0]),&(src->deck[0]), sizeof(Card) * (n));
// copy all cards up to the n-th point
memmove(&(tmpCards[n]),&(src->deck[n+1]), sizeof(Card) * (newSize - n));
// copy all cards from the n+1 -th point
src->size = newSize -1; // reevaluate size
src->deck = tmpCards; // reassign pointer
// since all input parameters were pointers, no return is necessary
}
Edit: to the people concerned by the fact that I don't release memory. The original code has 2 free commands in them (free(dest->deck) and free(src->deck)). but only one of them worked. The other created again memory corruption for some odd reason, so I found it better, not to put them into this example.
回答1:
I think you are running out of memory because you are not releasing any memory. You are only allocating new memory.
void moveCard(Deck *src, Deck *dest, int n){
Card *tmpCards = NULL;
Card tmp = (*src).deck[n]; // get card to be copied
int newSize = dest->size + 1; //increase dest size by 1
tmpCards = (Card *) malloc(sizeof(Card) * newSize); // allocate new memory area
memmove(&(tmpCards[0]), &(dest->deck[0]), sizeof(Card) * (newSize - 1));
// copy all the cards from old memory area to new area
// **** CORRECTION ****
// Free previously allocated memory for dest->deck
free(dest->deck);
dest->deck = tmpCards; // reassign old pointer to new memory area
dest->size = newSize; // reevaluate size
dest->deck[newSize - 1] = tmp; // copy card to end of new area
tmpCards = NULL; // empty out pointer (no functionality, just for easier reading)
newSize = src->size; // reevaluate newSize
tmpCards = (Card *) malloc(sizeof(Card) * (newSize - 1));
// allocate smaller mem area by 1
memmove(&(tmpCards[0]),&(src->deck[0]), sizeof(Card) * (n));
// copy all cards up to the n-th point
memmove(&(tmpCards[n]),&(src->deck[n+1]), sizeof(Card) * (newSize - n));
// copy all cards from the n+1 -th point
src->size = newSize -1; // reevaluate size
// **** CORRECTION ****
// Free previously allocated memory for src->deck
free(src->deck);
src->deck = tmpCards; // reassign pointer
// since all input parameters were pointers, no return is necessary
}
PS You should use memcpy instead of memmove. memmove is the right function to use if the source and the destination overlap. memcpy is the right function to use if the source and the destination do not overlap.
来源:https://stackoverflow.com/questions/27684119/c-method-for-moving-structs-between-dynamic-arrays