0

I'm working with grap. My graph is a structure like this

typedef struct{
  int order; // number of node
  int **mat; // matrix graphe
}graphe;

I'm working on school project and I need to build a set of binary's number from 0 to N (where is the order of the graph)

Actually I did this, it's working. When I'm printing the final variable, it displays all declinaison of binary number (000, 001, 010, 011, etc...)

char** construireSousEnsemble(graphe g){

  int size = pow(2, g.order);
  char** D = (char**)malloc(sizeof(char*)*g.order-1);

  for (int i = 0; i < size; i++){
    D[i] = (char*)malloc(g.order-1);
    char buffer[g.order-1];
    char tmp[g.order-1];
    char final[g.order-1];
    for (int j = g.order-1; j >= 0; j--){
      int bin = (i >> j)&1;
      sprintf(buffer, "%d", bin);
      snprintf(tmp, sizeof(tmp), "%s", buffer);
      strcat(final, tmp);
      if (j == 0){
        strcpy(D[i], final);
        //printf("%s\n", D[i]);
        //printf("%d | %s\n", i, D[i]);
        memset(final, 0, sizeof(final)); // reset the zone
      }
    }
    //printf("\n");
  }
  return D;
}

But in the main function, when I'm calling the function like this:

char** zones = construireSousEnsemble(g);

But when I'm printing the content with zones, I have this: enter image description here

So I'm a bit lost. This example is for a 3 nodes graph. If I have a 4 nodes, the weird symbol increase and I won't have 0001 or 0010 etc.., same with 5 or 6 nodes.

So my question is, why is this happening?

By the way, I'm not confortable with C so maybe I made some mistakes.

Thank you all :)

  • `-fsanitize=addr` is a great help at debugging these problems – ikegami Oct 28 '21 at 14:20
  • The size of D is off. Should be n^2-1. You use n-1. // The size of each element of `D` is also off. Should be n+1 (because of the NUL). You use n-1. – ikegami Oct 28 '21 at 14:24
  • `strcat(final, tmp);` You don't initialize the contents of `final` the first time through the loop. – 001 Oct 28 '21 at 14:24
  • ikegami: what is -fsanitize=addr? how do i use it? – Baptiste Leroux Oct 28 '21 at 14:28
  • An option you can pass to `gcc` or `clang`. (Use `@name` or people won't get notified.) – ikegami Oct 28 '21 at 14:29
  • @ikegami: I have added -fsanitize=address to my makefile rules, but i dont understand the output. And what you mean by "should be n²-1" and "each element of D is off"? – Baptiste Leroux Oct 28 '21 at 14:31
  • @JohnnyMopp: I have the ```char final[g.order-1];``` before the second loop so i'm initializing for the next loop no? – Baptiste Leroux Oct 28 '21 at 14:34
  • @BaptisteLeroux That creates the array but leaves its contents uninitialized - possibly filled with garbage. So when you `strcat` onto that you see the garbage characters. Initialize with `char final[g.order-1] = {0};`. – 001 Oct 28 '21 at 14:38
  • @JohnnyMopp when i'm adding the '= {0}' I have this error "variable-sized object may not be initialized" pointing on 'char' and this warning 'excess elements in array initializer' pointing on the 0 – Baptiste Leroux Oct 28 '21 at 14:43
  • Okay, then just initialize the first element so you have an empty string: `char final[g.order-1]; final[0] = '\0';` – 001 Oct 28 '21 at 14:46
  • @JohnnyMopp i still have the garbage characters :/ – Baptiste Leroux Oct 28 '21 at 14:48
  • @Baptiste Leroux Re "*what you mean by "should be n²-1"*", You try to add n²-1 strings (001, 010, 011, ..., 111) to `D`, but you don't allocate that much memory. ///Re "**each element of D is off*"? I said the *size* is off. You don't allocate the right amount of memory – ikegami Oct 28 '21 at 14:51
  • @ikegami so what's the malloc then? – Baptiste Leroux Oct 28 '21 at 14:53
  • My original comment already indicates how many elements need to be allocated. – ikegami Oct 28 '21 at 14:54
  • Re "*I have added -fsanitize=address to my makefile rules, but i dont understand the output.*", Feel free to ask a Question about it. – ikegami Oct 28 '21 at 14:55
  • @ikegami i dont understand why you said it's n² because for 3 node im my graphe, i have 8 possibilty so it's 2^n instead? And i dont understand why im not allocating the right amount of memory for D[i] because i want my string to be the same length of the number of node in the graph. And (last thing), all the elements execpt the first ones is printing correctly – Baptiste Leroux Oct 28 '21 at 15:00
  • I'm not sure why you need `size`. You want to create an array of `char *` so there should be `g.order` rows and `g.order + 1` columns (the +1 for the '\0' c-strings require). Try this: https://onlinegdb.com/CKJksWSjV – 001 Oct 28 '21 at 15:06
  • I need size because i need to store all the 2^n binary number (from 0 to n-1) – Baptiste Leroux Oct 28 '21 at 15:09
  • @JohnnyMopp i have tested your solution, its working but for a 5 node graph, i want all the 2⁵ binary number (00000, 00001, ... 11111) Edit: ok its working, i've just update the malloc for the `char **D = (char **) malloc (sizeof (char *) * size); with `int size = pow(2, g.order);` and its working :) – Baptiste Leroux Oct 28 '21 at 15:16
  • Ok, I didn't get that from the question. Try this: https://onlinegdb.com/M7Qn_4aM1f – 001 Oct 28 '21 at 15:21

1 Answers1

0

Here is the solution (posting if for the future)

char ** construireSousEnsemble(graphe g){
    int size = pow(2, g.order);
    char **D = (char **) malloc (sizeof (char *) * size);

    char buffer[g.order];
    char final[g.order];

    for (int i = 0; i < size; i++) {
        D[i] = (char *)malloc(g.order + 1);
        final[0] = 0;
        for (int j = g.order - 1; j >= 0; j--) {
            int bin = (i >> j) & 1;
            sprintf (buffer, "%d", bin);
            strcat (final, buffer);
        }
        strcpy (D[i], final);
    }
    return D;
}
  • It is nice to show the working solution. But in C you really [should not cast malloc](https://stackoverflow.com/q/605845/3545273)... – Serge Ballesta Oct 28 '21 at 15:23