0

To preface: I am new to C and still learning the best way to efficiently code in C.

I'm trying to create an dynamic array of structs. I have an array within the struct however the values within the array are being overwritten by the values that come after it.

struct dir {
    int size;
    int *parameters;
};

Here I am placing all values I read from the file into a temporary char array called vars2. I cross check the index of the string with a 2D vars array of strings to find the index of the value. If the index is not found I copy the value into the 2D vars array so an index can be assigned to it if later instructions calls for the new variable. length is the length/size of the 2D array.

I then assign the node to an index, reallocate memory for the next node, and move on to read the next set of instructions in the file.

The struct array is dependent on the number of instructions within the file. The number of instructions is unknown until we reach the end of file, that is why I do not increment it until the end of the loop. I have tried to increment it at the beginning of the loop, but it did not make a difference.

int numinstruct = 0;
struct dir *gates = malloc(1*sizeof(struct dir));
while (fscanf(fp, "%s", gate) == 1) {
        struct dir node;

// code that reads from file are in between that assigns the struct size and type of gate
// node.size is the size of the array that was read from the file; parameters array is a   static array

        node.parameters[node.size];
     
        for (i = 0; i < node.size; i++) {
            fscanf(fp, " %16s", vars2);
            int index = indexLookup(vars, vars2, length);
            if (index != -1) {
                node.parameters[i] = index;
            } else {
                vars = realloc(vars, (length+1)*sizeof(char*));
                vars[length] = malloc(17*sizeof(char));
                strcpy(vars[length], vars2);
                node.parameters[i] = length;
                length++;
            }
        }

        gates[numinstruct] = node;
        numinstruct++;
        gates = realloc(gates, (numinstruct+1)*sizeof(struct dir));
    }

All data are placed within the actual node and not the array itself. I have tried to place the data within the array itself, as seen below. However, the program would stop/crash once it got to the parameters section of the code.

typedef struct {
    int size;
    int *parameters;
} DIR;

DIR *gate = malloc(1*sizeof*gate);

// code in between

int numinstruct = 0;
struct dir *gates = malloc(1*sizeof(struct dir));
while (fscanf(fp, "%s", gate) == 1) {
        struct dir node;

// code that reads from file are in between that assigns the struct size and type of gate
// node.size is the size of the array that was read from the file; parameters array is a   static array

        gate[numinstruct].parameters[ gate[numinstruct].size];
     
        for (i = 0; i <  gate[numinstruct].size; i++) {
            fscanf(fp, " %16s", vars2);
            int index = indexLookup(vars, vars2, length);
            if (index != -1) {
                gate[numinstruct].parameters[i] = index;
            } else {
                vars = realloc(vars, (length+1)*sizeof(char*));
                vars[length] = malloc(17*sizeof(char));
                strcpy(vars[length], vars2);
                 gate[numinstruct].parameters[i] = length;
                length++;
            }
        }

        numinstruct++;
        gates = realloc(gates, (numinstruct+1)*sizeof*gates);
    }

The thing I find most confusing is that the size variable does not get overwritten. The only values that get overwritten are the values within the parameters array. There isn't any code written before it that touches the parameter array, only the segment that I have provided which fills the parameter array with values.

For instance:

instruction 1: size = 2; param = {2, 3, 5}; instruction 2: size = 3; param = {3, 6, 8};

Once I read the instructions and print them out, outside of the loop I get the following:

instruction 1: size = 2; param = {3, 6, 8}; instruction 2: size = 3; param = {3, 6, 8};

  • 1
    Please provide a [mre] instead of snippets of code. What is particular powerful way of communicating the issue is to hard-code a failing test case. – Allan Wind Dec 02 '22 at 20:22
  • "I have an array within the struct" - No, you don't. You have a pointer in the struct. And you don't show any code that initializes that pointer in any instance of that struct, though you do dereference it. That is undefined behavior. Either convert parameter to an actual fixed size array or set it to point to an appropriately sized buffer obtained from malloc() before dereferencing it. – Avi Berger Dec 02 '22 at 20:52
  • If "parameters array is a static array" means that in code not shown you have something like `static int buff[15]; . . . gate[numinstruct].parameters = buff;`, then my previous comment is wrong and you have one buffer that you are sharing between all instances of your struct. In that case when you change its contents, you are doing so for _all_ the struct instances that are referring to it. – Avi Berger Dec 02 '22 at 21:09
  • @AviBerger This helped me figure things out a bit. I didn't know that by declaring it as a static array the values are being overwritten for all instances. I found that if I use malloc to allocate memory to the array, the values do not get overwritten. Is there a way to change items within a static array so values are not being overwritten? – Skyttlez Dec 02 '22 at 21:39
  • A pointer just points to whatever array you point it at. It does not contain that array and the array knows nothing about it. If you set a bunch of pointers to the same array (static or not), when you change the array, it will be changed. Doesn't matter which pointer you use to access it. By using malloc, you can obtain different array instances to associate with the pointers in different struct instances so they can function independently. (Remember to free the buffers when done with them.) – Avi Berger Dec 02 '22 at 23:21
  • BTW what is `1*sizeof*gate` in line 6 meant to be? – Markus Dec 03 '22 at 21:42
  • @Markus I was trying to initialize the gate array, but due to typos I left out the parenthesis. I also thought I needed to add 1 to allocate 1 space of memory to gate. It should be `sizeof(*gate)` But I realize now I do not need the 1. – Skyttlez Dec 05 '22 at 04:41
  • Did you find a solution of your problem after all the comments? If not, you should update your question with a minimal reproducible example (main + includes + test data) of your current issue. Otherwise people will think that this question is solved or you aren't interested anymore. – Markus Dec 05 '22 at 10:17
  • @Markus Yes I was able to find a solution after all of the comments. Is there a way to update the post as solved? – Skyttlez Dec 05 '22 at 13:08
  • You can post your solution as answer (see below) and and then set it to accepted. This way you can help others with a similar issue. – Markus Dec 05 '22 at 14:33

0 Answers0