0

I have an assignment to do for my Data Structures class and I'm in a little bit of trouble. I have some structures, namely:

typedef struct {
    char *materie;
    int ore_curs;
    int ore_lab;
    int credit;
    int teme;
} TMaterie;

typedef struct {
    char *nume;
    float medie;
    char grupa[6]; // 324CB + NULL
    int varsta;
} TStudent;

typedef struct {
    void *key;
    void *value;
    int frequency;
} Pair;

typedef struct celulag {
  void *info;
  struct celulag *urm;
} TCelulaG, *TLG, **ALG;

The last one is a generic list structure that will accept in the info any kind of structure. The thing is that I need to convert it to the structure pair so that it will point out to a key (that will be either a char or an int) and a value (that will be of the type TMaterie or TStudent). I need to make functions that allocate that accordingly and I have managed to do this:

TLG aloca_string_materie(char *key, TMaterie value){
    TLG cel = (TLG) malloc(sizeof(TCelulaG));
    if(!cel)
        return NULL;
    cel->info = (Pair*)malloc(sizeof(Pair));
    if( !cel->info){
        free(cel);
        return NULL;
    }
    cel->urm = NULL;
    ((Pair*)cel->info)->value = (TMaterie*)malloc(sizeof(TMaterie));
    ((Pair*)cel->info)->key = (char*)malloc(50*sizeof(char));
    ((Pair*)cel->info)->frequency = 0;
    ((Pair*)cel->info)->key = key;
    ((TMaterie*)(Pair*)cel->info)->materie = value.materie;
    ((TMaterie*)(Pair*)cel->info)->ore_curs = value.ore_curs;
    ((TMaterie*)(Pair*)cel->info)->ore_lab = value.ore_lab;
    ((TMaterie*)(Pair*)cel->info)->credit = value.credit;
    ((TMaterie*)(Pair*)cel->info)->teme = value.teme;
    return cel;
}

The problem that I am facing is that when I try to print out the key, namely

(((Pair*)cel->info)->key)

it gives me the same value as

((TMaterie*)(Pair*)cel->info)->materie 

and I have no idea why.

Can someone please tell me what I'm doing wrong?

LPs
  • 16,045
  • 8
  • 30
  • 61
  • 1
    [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Apr 05 '17 at 12:38
  • Also, I have to say that there should be 4 functions, each of them allocating like this: 1 (key -- string, value -- TStudent), 1 (key -- int, value -- TStudent) and so on. – Vaduva Mihaita Bogdan Apr 05 '17 at 12:39
  • 2
    This is why I hate typedefing pointers.....sigh... – Sourav Ghosh Apr 05 '17 at 12:39
  • Detail: "last one is a generic list structure that will accept in the info any kind of structure." Disagree, `info` can save object pointers, not structures. – chux - Reinstate Monica Apr 05 '17 at 12:47
  • @SouravGhosh that still doesn't solve my problem. :( if I print the key in the function ( ((Pair*)cel->info)->key) it gives me the right value. But when I assign (((TMaterie*)(Pair*)cel->info)->materie = value.materie) then the correct key value is gone. – Vaduva Mihaita Bogdan Apr 05 '17 at 12:47
  • @chux, yes, you are right, I'm sorry. Info will save pointers to structures. – Vaduva Mihaita Bogdan Apr 05 '17 at 12:48
  • `key` seems a string. Use `strcpy()` to copy string to it. – LPs Apr 05 '17 at 12:50
  • `((TMaterie*)(Pair*)cel->info)->materie = value.materie;` ----> `((TMaterie*)((Pair*)cel->info)->value)->materie = value.materie;` – LPs Apr 05 '17 at 12:52

2 Answers2

2

The problem is you are overwriting the pointer value instead of writing to the buffer it points to. You are doing the following:

  ((Pair*)cel->info)->key = malloc(...);
  ((Pair*)cel->info)->key = key;

In the second line you asign the pointer whatever is passed in the key argument, so you are not using the memory you have allocated above and it is being leaked.

What you probably want is to copy the contents pointed by the key argument, you can use the strcpy function. Do something like:

  ((Pair*)cel->info)->key = malloc(...);
  strcpy(((Pair*)cel->info)->key, key);
Elvis Teixeira
  • 604
  • 4
  • 13
2

You have two main problems

((Pair*)cel->info)->value = (TMaterie*)malloc(sizeof(TMaterie));
[...]
((TMaterie*)(Pair*)cel->info)->materie = value.materie;

TMaterie member into Cel->info is value, so

((TMaterie*)(Pair*)cel->info)->materie

must be

((TMaterie*)((Pair*)cel->info)->value)->materie

Moreover using

((Pair*)cel->info)->key = (char*)malloc(50*sizeof(char));
[...]
((Pair*)cel->info)->key = key;

You are overwriting memory mallocated for key. If, as I guess, key is a string, just use strcpy

((Pair*)cel->info)->key = (char*)malloc(50*sizeof(char));
[...]
strcpy(((Pair*)cel->info)->key, key);
LPs
  • 16,045
  • 8
  • 30
  • 61