1

This program is supposed to create a dynamic memory vector. I'm pretty sure I'm using malloc correctly. My real problem is some syntax with pointers, particularly a pointer inside a struct.

I'm trying to access the address of an int pointer inside a struct so I can assign it to another pointer

My given struct is:

typedef struct{
int *items;
int capacity;
int size;
}VectorT;

and the function I'm trying to get to work is:

int getVector(VectorT *v, int index){
    int *p;
    p = v->items;//(2)
    p -= v->size;
    p += index;
    return *p;
}

This is supposed to take the address of the items pointer subtract the number of items in the list and add the index of the desired item to the address of p. Then I return what is at the address of p.

I have a pretty strong feeling that line (2) is not the syntax I need.

Depending on what I've tried so far my program either crashes when getVector is called or it outputs (my best guess) some memory locations.

Here's the code that adds a vector:

void addVector(VectorT *v, int i){
        if(v->size >= v->capacity){
            //allocate twice as much as old vector and set old pointer to new address
            v = (VectorT *) malloc(2 * v->capacity * sizeof(VectorT));
            if(v == NULL){
                fprintf(stderr, "Memory allocation failed!\n");//error catch
            }
            else{
                v->capacity *= 2;//double the reported capacity variable
                v->size++;//add one to the reported size variable
                v->items =(int *) i;//add the item to the vector (A)<-----
            }   
        }
        else{
            v->size++;//add one to the reported size variable
            v->items =(int *) i;//add the item to the vector (B)<-----
        }
}

I don't feel like my problem is in here, but if it is I have some suspicion at lines A & B...

Any insight would be much appreciated, Thanks!

Matt
  • 22,721
  • 17
  • 71
  • 112
PilHliP
  • 21
  • 1
  • 1
  • 4

3 Answers3

3

Your dealing with pointers is wrong in at least these places:

  • The code with the comment "add the item to the vector" is very wrong: instead of adding an item, it overrides the pointer with an arbitrary int.

v->items =(int *) i;

should be

*(v->items) = i;
  • Your pointer arithmetic is incorrect: subtracting the size and adding an index will get you a pointer prior to the beginning of the allocated area, which is not correct.

  • You are assigning the results of malloc to a local variable v of type "pointer to vector". This assignment has no effect in the caller, because pointers are passed by value. If you wanted to re-assing the vector in the addVector, you should have taken VectorT **pv as the first parameter. This code fragment does not look right at all: it appears that you should be assigning v->items=malloc(2 * v->capacity * sizeof(int)) instead of v=malloc(...)

  • You do not free the old vector when you do a malloc, causing a memory leak.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • thanks, *(v->items) = i seems good. How should I properly subtract the size and add the index? – PilHliP Jul 02 '12 at 19:26
  • @user1496866 Conventionally the pointer `items` points to the beginning, not to the end of the memory interval allocated to your vector. You do not need to subtract the size, simply add the index. Please see the edit to the third point, too: it looks like you are allocating a memory for a wrong thing. – Sergey Kalinichenko Jul 02 '12 at 19:31
  • I need to have the pointer pointing to the last element in the list. would v->items++ increment the items pointer? – PilHliP Jul 02 '12 at 19:38
  • @user1496866 Don't forget to copy what the `v->items` was pointing to into the newly allocated area, and free the old pointer. [Here](http://fydo.net/gamedev/dynamic-arrays) is a decent tutorial on the subject. – Sergey Kalinichenko Jul 02 '12 at 19:54
1

You want the address of i, therefore:

v->items =&i;//add the item to the vector (A)<-----

Also, when calculating the size you'll want:

p -= (v->size*sizeof(int));

UPDATE:

You can also pass a pointer to i into getVector and just save that in v->items

 int getVector(VectorT *v, int *index)
 //...
 v->items = i;
peacemaker
  • 2,541
  • 3
  • 27
  • 48
  • is i stored in a memory location that's contents won't get wiped out after the function exits? My understanding was that if I put the address into v->items, the variable at &i might not be i after the function ended. I could be wrong though. – PilHliP Jul 02 '12 at 19:16
  • You're correct. In that case, you'll want to pass i into `addVector` as a pointer, then just do `v->items = i` – peacemaker Jul 02 '12 at 19:17
  • I wish I could, my professor, provided the function definitions. I really don't see another way to do it though. I'll keep trying &i and (int *) i one of those ways might work. I think I have some more problems besides that section, however. Still getting some funky outputs even with sizeof.. – PilHliP Jul 02 '12 at 19:22
  • Ahh it's homework! Ok, well it looks like `int *items` is supposed to be an array of integers and you're assigning it wrong. You'll want to copy the value to the end of the array, rather than just changing `*items` as that is the start pointer to the array – peacemaker Jul 02 '12 at 20:00
1

I see you're allocating memory for VectorT when you should be allocating memory for VectorT.items

void addVector(VectorT *v, int i){
        if(v->size >= v->capacity){
            //allocate twice as much as old vector and set old pointer to new address
            v->items
            int* tmp = malloc(2 * v->capacity * sizeof(int));
            if(tmp == NULL){
                fprintf(stderr, "Memory allocation failed!\n");//error catch
            }
            else{
                int j;
                for (j = 0; j < v->size; j++){
                    tmp[j] = v->items[j];
                }
                free(v->items);
                v->items = tmp;
                v->capacity *= 2;//double the reported capacity variable
                v->items[v->size] = i;//add the item to the vector (A)<-----
                v->size++;//add one to the reported size variable
            }   
        }
        else{
            v->items[v->size] = i;//add the item to the vector (B)<-----
            v->size++;//add one to the reported size variable
        }
}

int getVector(VectorT *v, int index){
    return v->items[index]
}
Musa
  • 96,336
  • 17
  • 118
  • 137
  • @user1496866 Take a read http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/ – Musa Jul 02 '12 at 19:54
  • then you'll have to manually copy the buffer from the old buffer to the new bigger buffer – Musa Jul 02 '12 at 20:00