1

I'm having problems with my code:

Here is when i set up the values of valor1,valor2,valor3 in 3 unions and i save then inside the struct "estrucuras".

union atributo{
    int valor1;
    char *valor2;  
    float valor3;
};


struct estructura{
    int *tipo;
    union atributo *list;

};

union atributo *atributos;  
struct estructura *estructuras;

estructuras = malloc (sizeof(struct estructura) * (cantEstruct) );

int cantEstruct=2;
int tamEstruct=3;
srand(rdtsc());
for(i=0;i<cantEstruct;i++){
    estructuras[i].list=malloc(sizeof(union atributo) * tamEstruct);
    for (j=0;j<tamEstruct;j++){


       switch ((tiposAtributos[j])) {

       case 1:

            estructuras[i].tipo[j]=1;
            estructuras[i].list[j].valor1= rand()%10000000;
            printf("Saving %d\n", estructuras[i].list[j].valor1);
            break;


       case 2:      
            estructuras[i].tipo[j]=2;
            tamChar = 10;
            estructuras[i].list[j].valor2 = malloc(sizeof(char) * (tamChar+1));
            for(k=0;k<tamChar;k++){
                estructuras[i].list[j].valor2[k]= 'A' + ( rand() % ( 'Z' - 'A'));

            }
            estructuras[i].list[j].valor2[k] = '\0';
            printf("Saving %s\n",estructuras[i].list[j].valor2);

    break;

    case 3:
    estructuras[i].tipo[j]=3;
            float valor1=(((float)rand())+1.0)*500000.0;
            float valor2=(((float)rand())+1.0)*25.0;
            estructuras[i].list[j].valor3=valor2/valor1;
            printf("Saving %.25f\n", estructuras[i].list[j].valor3);

    break;

     }
}

}

Here is when i get and print the values and where the problem is:

for(i=0;i<cantEstruct;i++){
printf("Valores de la estructura %d\n", i);
for (j=0;j<tamEstruct;j++){

    switch (tiposAtributos[j]) {

    case 1:


    //atributos=malloc(sizeof(union atributo));                 
    //*atributos = estructuras[i].list[j];                  
    //printf("Valor del atributo %d\n",atributos->valor1);
    printf("Value %d\n", estructuras[i].list[j].valor1);                        

    break;

    case 2:

    //atributos=malloc(sizeof(union atributo));                 
    //*atributos = estructuras[i].list[j];

    //printf("Valor del atributo%s\n",atributos->valor2);

            printf("Value %s\n",estructuras[i].list[j].valor2);         
    break;

    case 3:

    //atributos=malloc(sizeof(union atributo));                     
    //*atributos = estructuras[i].list[j];
    //printf("Valor del atributo %.25f\n",atributos->valor3);
    printf("Value %.25f\n", estructuras[i].list[j].valor3);                 
    break;

        }

  }
}

Now works for any valor in tamEstruct. But still crashing when i try to make more than one struct.

Here i show u the problem when i execute it for more than 1 estruct:

Saving 4089113
Saving UBJPXTWDJA
Saving 0.0001530080626253038644791
*** Process received signal ***
Signal: Segmentation fault (11)
Signal code: Address not mapped (1)
Failing at address: (nil)

Now save the first struct but crash with the second one. I tryed this:

estructuras[i].list=malloc((sizeof(char)*(tamChar+1) * (tamEstruct)));

But dosnt works.

I will appreaciate any answer. Thank you for your time.

timrau
  • 22,578
  • 4
  • 51
  • 64
Niemand
  • 127
  • 1
  • 12
  • [Please don't cast the return value of `malloc()` in C](http://stackoverflow.com/a/605858/28169). – unwind Nov 06 '13 at 14:07

2 Answers2

1

You need to move the line that initializes estructuras[i].list to outside of the second loop, like this:

for(i=0;i<cantEstruct;i++){
    estructuras[i].list=malloc(sizeof(union atributo) * tamEstruct);
    estructuras[i].tipo=malloc(sizeof(int) * tamEstruct);
    for (j=0;j<tamEstruct;j++){
        ...
    }
}

Your current code keeps re-initializing the entire list for each attribute, so only the last one ends up with correct values, and all the prior ones get leaked. That is why your printing function prints incorrect values - that's uninitialized values in the list.

EDIT : (in response to the edit of the question)

Your assignments in the switch statement are incorrect as well. You do not need to malloc a new uinon attribute - you can modify the union in place, like this:

srand(rdtsc()); // Move this line to outside the loops
...
switch ((tiposAtributos[j])) {
    case 1:
        estructuras[i].tipo[j]=1;
        estructuras[i].list[j].valor1= rand()%10000000;
        printf("Saving %d\n", estructuras[i].list[j].valor1);
        break;
    case 2:      
        estructuras[i].tipo[j]=2;
        tamChar = 10;
        estructuras[i].list[j].valor2 = malloc(tamChar+1);
        for(k=0;k<tamChar;k++){
            estructuras[i].list[j].valor2.valor2[k]= 'A' + ( rand() % ( 'Z' - 'A'));

        }
        estructuras[i].list[j].valor2.valor2[k] = '\0';
        printf("Saving %s\n",estructuras[i].list[j].valor2);
        break;
    case 3:
        estructuras[i].tipo[j]=3;
        float valor1=(((float)rand())+1.0)*500000.0;
        float valor2=(((float)rand())+1.0)*25.0;
        estructuras[i].list[j].valor3=valor2/valor1;
        printf("Saving %.25f\n", estructuras[i].list[j].valor3);
        break;
 }

Note: in C you do not need to cast malloc's results, so I removed the unnecessary cast.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thank you for the fast answer. i will edit the code because now i'm having a problem with more than one estructure or more than 3 unions. – Niemand Nov 06 '13 at 14:15
  • I edited, now at least is saving one value, and sometimes 3. But it still giving me the error. Thank you for the previous assistance. – Niemand Nov 06 '13 at 14:50
  • @Niemand You need to add `+1` here: `estructuras[i].list[j].valor2 = malloc(tamChar+1);` – Sergey Kalinichenko Nov 06 '13 at 15:16
  • i edited it like this: estructuras[i].list[j].valor2 = malloc(sizeof(char) * (tamChar+1)); And now it works ,as i explain in the post, for many unions but not for more than one struct. – Niemand Nov 06 '13 at 17:02
  • @Niemand You need to allocate `estructuras = malloc(cantEstruct*sizeof(struct estructura));` is this how you do it? – Sergey Kalinichenko Nov 06 '13 at 17:08
  • Yes, i do estructuras = malloc(sizeof(struct estructura)*cantEstruct); at the begining, but i think it should be wrong, because at the second struct it crash. EDITED: Srry, i forgot the line in the code, but i do it. – Niemand Nov 06 '13 at 17:18
  • @Niemand You need to add `estructuras[i].tipo=malloc(sizeof(int) * tamEstruct);` (see edit). – Sergey Kalinichenko Nov 06 '13 at 17:23
  • Thank you for all, i worried so much about the others variables and i forgot the variable "tipo". Now it works perfect. I can go ahead with my MPI implementation. THANK YOU! – Niemand Nov 06 '13 at 17:30
1

Your problem is that you keep overwriting your list:

for(i=0;i<cantEstruct;i++){
    for (j=0;j<tamEstruct;j++){
       estructuras[i].list=(union atributo *)malloc(sizeof(union atributo) * tamEstruct);

should be:

for(i=0;i<cantEstruct;i++){
    estructuras[i].list=(union atributo *)malloc(sizeof(union atributo) * tamEstruct);
    for (j=0;j<tamEstruct;j++){
noelicus
  • 14,468
  • 3
  • 92
  • 111