byj byj - 17 days ago 7
C Question

Unable to properly use struct pointers in C

I am a beginner with C and currently struggling with using structs in functions. Even tho I give my functions the pointer to my struct and use that to change their values it seems like my functions are unable to change the value of the pointer themselves

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>

typedef struct Vector
{
int n;
double *entry;
}Vector;

//defining the struct vector with n for its length and entry as a pointer which will become an array for its values
Vector *newVector(int n)
{
int i = 0;
Vector *X = NULL;
assert(n > 0);
X = malloc(sizeof(Vector));
assert(X != NULL);
X->n = n;
X->entry = malloc(n+1*sizeof(double));
assert(X->entry != NULL);
X->entry[0] = 0;
for (i=1; i<n+1; ++i) {
scanf("%lf",&X->entry[i]);
}
return X;
}

//making a new vector struct from the size given and returning its pointer (the array is made so it goes from 1-n instead of 0-(n-1)
void delVector(Vector *X)
{
assert(X != NULL);
assert(X->entry != NULL);
free(X->entry);
free(X);
X = NULL;
}

int getVectorLength (Vector *X)
{
assert(X != NULL);
return X->n;
}

void setVectorLength(Vector *X, int k)
{
assert(X != NULL);
assert(k>0);
delVector(X);
printf("so far.\n");
X = newVector(k);
} //deleting the vector and then replacing it with the new sized vector

double getVectorEntry (Vector *X, int h)
{
return X->entry[h];
}

void setVectorEntry (Vector *X, int h)
{
printf("Value %d.\n",h);
scanf("%lf",&X->entry[h]);
}

main()
{
Vector *h = NULL;
h = newVector(3);
printf("%f\n",h->entry[1]);
printf("%f\n",getVectorEntry(h,1));
setVectorEntry(h,1);
printf("%f\n",getVectorEntry(h,1));
printf("%d\n",getVectorLength(h));
setVectorLength(h,6);
printf("%f\n",getVectorEntry(h,6));
setVectorEntry(h,6);
printf("so far.\n");
printf("%f\n",getVectorEntry(h,6));
}


Running the code would make it crash once it reaches delVector. If I were to comment the delVector out it would crash at
X = newVector(k);
for a reason I also cannot find out (it starts the function newVector, but crashes before I can input). So what is causing the errors?
Thanks a lot in advance!

Answer

Let's just focus on the setVectorLength function

void setVectorLength(Vector *X, int k)
{
    assert(X != NULL);
    assert(k>0);
    delVector(X);
    printf("so far.\n");
    X = newVector(k);
}

Here, Vector *X is a local variable that only exists in this function. It points to some location in memory, but using it you can't modify the original pointer. So there are two ways around it. 1. You don't delete and recreate the vector. Instead do something like this

void setVectorLength(Vector *X, int k)
{
    X->entry = realloc(X->entry, k*sizeof(double)); // frees X->entry and allocates it to a new heap array
    X->k = k;
}

2. Use a pointer pointer. Do note, that this will be slower and is unnecessary. Go for the 1 solution.

void setVectorLength(Vector **X, int k)
{
    assert(*X != NULL);
    assert(k>0);
    delVector(*X);
    printf("so far.\n");
    *X = newVector(k);
}

The variable Vector **X points to the original variable, so you can modify it.