0

I'm trying to add a card into my Vect->Items card array, but I'm getting an access writing violation in my add at the Items array address. Is there something wrong with the initialization of the vector? The access writing violation occurs at the address of initialized vector, but I don't understand why it would be an error if it's just initializing.

void VectorInit(Vector * vect, int capacity)
{
    vect->size = 0;             //initialize the size to 0 (no elements)
    vect->capacity = capacity;  //initialize capacity to 10, can grow later


    vect->Items = (Card *)malloc(sizeof(Card)* vect->capacity); //alloc mem space for Items array = size of an int * capacity alloted
}

void Grow(Vector * vect)
{
    int i;

    if (vect->capacity < 0) //if the capacity ever reaches 0 or below, reset it to 10
        vect->capacity = 10;
    else
        vect->capacity *= 2; // 'grow' the capacity by doubling it

    Card *newStore = (Card *)realloc(vect->Items, (vect->capacity) * sizeof(Card)); //realloc size for newStore

    if (!newStore)
    {
        newStore = (Card*)malloc(vect->Items, (vect->capacity * sizeof(Card)));

        for (i = 0; i < vect->size; ++i)
        {
            newStore[i] = vect->Items[i]; //copy original values into larger int array
        }

        free(vect->Items); //free space
        vect->Items = newStore; //point items int array to new int ptr
        newStore = 0; //best practice
    }

}
void Add(Card card, Vector * vect)
{
    if (vect->size == vect->capacity) //if the num of elements = capacity, the array is full - Grow it
        Grow(vect);
    vect->Items[vect->size] = card;        //add a provided index and value for insertion in Items array
    ++vect->size;//increment the size so the pointer points to the next available spot

}

.h

typedef enum {Clubs,Diamonds,Hearts,Spades} Suits;
typedef enum{Deuce = 2,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Jack,Queen,King,Ace} Face;

typedef struct card
{
    Suits suit;
    Face face;

} Card;

typedef struct vector
{
    Card * Items; //pointer to array of cards
    int size; //current num of elements
    int capacity; //max num of elements

}Vector;


void VectorInit(Vector * vect, int capacity);
void Grow(Vector * vect);
void Add(Card card, Vector * vect);

main.c

Vector Deck;

VectorInit(&Deck, 52);

Card test;

test.face = (Face)2;
test.suit = (Suits)1;

Add(test, &Deck);
V.M
  • 71
  • 1
  • 9
  • 1
    [don't cast malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Dec 14 '18 at 23:16
  • 1
    You have not assigned the new value `newStore` to `vect->Items` when the reallocation was successful. – Weather Vane Dec 14 '18 at 23:22
  • 1
    Consider a [mcve] with code that compiles. `malloc(vect->Items, (vect->capacity * sizeof(Card)));` doesn't compile for me, and when I correct it, the code does not crash. – Retired Ninja Dec 14 '18 at 23:22
  • 1
    Your code in the `if (!newStore)` block is basically doing the same thing that `realloc()` does. If `realloc()` fails, there's no reason to expect that `malloc()` will succeed. – Barmar Dec 14 '18 at 23:24
  • And you never check whether `malloc()` succeeds! – Barmar Dec 14 '18 at 23:25
  • I don't think `++vect->size;` does what you think it does, because of operator precedence. It should be `vect->size++;` or `++(vect->size);` – Barmar Dec 14 '18 at 23:31

1 Answers1

0

Like people said in the comments the code you're doing inside if(!newStore) is redudant because since realloc() failed malloc() will possible fail too. And mainly you're forgeting to update vect->Items with the newStore. Therefore you should end up with something like this:

void VectorInit(Vector *vect, int capacity) {
    vect->size = 0;
    vect->capacity = capacity;
    vect->Items = malloc(sizeof(Card) * capacity);
}

void Grow(Vector *vect) {
    if (vect->capacity < 0) vect->capacity = 10;
    else vect->capacity *= 2;

    Card *newStore = realloc(vect->Items, vect->capacity * sizeof(Card));
    vect->Items = newStore;
}

void Add(Card card, Vector *vect) {
    if (vect->size == vect->capacity) Grow(vect);
    vect->Items[vect->size++] = card;
} 
chriptus13
  • 705
  • 7
  • 20
  • 2
    Notice that [malloc](https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm) only takes one parameter instead of two as you were using in the line `newStore = (Card*)malloc(vect->Items, (vect->capacity * sizeof(Card)));` – chriptus13 Dec 14 '18 at 23:48