2

I've been struggling to make a dynamically changing array of structures in C. My array size should change depending on how many times user decides to write data (city1 city2 and distance). I'm talking about addEdge function, which is supposed to make a bigger array every time user inputs data; it's also supposed to store structures in this array. I've used realloc function but it doesn't seem to work. In my main function I ask user to write his data twice and start my function after every input. It, for some reason, works after first function initialization, but it crashes after the second time. My intention is that it worked in a loop (user adds as much data as he wants). Here's the code:

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct edge{
   char city1[30];
   char city2[30];
   int distance;
}edge;
void addEdge(edge **tab, char* city1, char* city2, int distance, int* n);
int main()
{
    edge *tab;
    tab=(edge*)malloc(0);
    char city1[30], city2[30];
    int distance, n=1;
        printf("\nType cities and distance in form: 'city1 city2 distance'\n");
    scanf("%s %s %d", city1, city2, &distance);
    addEdge(&tab, city1, city2, distance, &n);


        printf("\nType cities and distance in form: 'city1 city2 distance'\n");
    scanf("%s %s %d", city1, city2, &distance);
    addEdge(&tab, city1, city2, distance, &n);


    system("pause");
    return 0;
}


void addEdge(edge **tab, char* city1, char* city2, int distance, int* n)
{

    edge edgeN;
    strcpy(edgeN.city1, city1);
    strcpy(edgeN.city2, city2);
    edgeN.distance=distance;
    *tab=(edge*)realloc(*tab, *n * sizeof(edge));
    *tab[*n-1]=edgeN;
    *n=*n+1;

}
8
  • 2
    What exactly are you expecting malloc(0) to do? Commented Dec 29, 2017 at 22:47
  • Not anything really, something started working after I did that so... // edit: after I deleted that, it crashes after first initialization of the function... so it's like... important in some way Commented Dec 29, 2017 at 22:49
  • Isn't that covered in: *n=*n+1; ? Commented Dec 29, 2017 at 22:55
  • @rgornicka @klutt Indeed, malloc(0) is in a way important, because realloc() needs to get a pointer previously returned by malloc(). From realloc's man page: * Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc(), or realloc()* Commented Dec 29, 2017 at 22:57
  • 1
    Lots of potential problems. For one, you never check the return value from scanf(), so you don't know if there's garbage in your city1 and city2 arrays. Commented Dec 29, 2017 at 23:04

2 Answers 2

3

You have fallen in an operator precedence trap. *tab[*n-1]=edgeN; is compiled as *(tab[*n - 1]), when what you want is (*tab)[*n - 1];.

When in doubt, use parens, they may be useless, but it would be harmless.

This is the real cause for your problems, but you should also follow Stargateur's advice and test the return values of all input and allocation functions.

Sign up to request clarification or add additional context in comments.

Comments

3

One of your mistake is that you never check any possible failure of your function call. scanf() return the number of field valid or an error, malloc() or realloc() can return an error.

edge *tab = NULL;
size_t n = 1; // should be size_t and not int
// ...
if (scanf("%29s %29s %d", city1, city2, &distance) != 3) {
    fprintf(stderr, "wrong input\n");
    exit(EXIT_FAILURE);
}
// ...
edge *tmp = realloc(*tab, *n * sizeof *edge);
if (!tmp) {
  exit(EXIT_FAILURE);
}
*tab = tmp;

4 Comments

I downvoted you because, even though what you are saying is a good advice, it does not address the problem asked, so it can be misleading to others.
@KyrSt I think you misunderstood the purpose of answer in stackoverflow ;) but I will update my answer, I indeed didn't see one of the many problem of this question.
Indeed, it is never mentioned in help center that answers must point exactly to the problem and not giving other advice. I took my vote back, but I still believe that in the form of an answer it is confusing to other people having the same problem, as your answer by itself does not solve the OP's error.
OP's code have numerous short-comings. Some more critical than others. This answers IDs 4 of them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.