Niemand
Niemand

Reputation: 127

Printing wrong values on pointers to structs

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.

Upvotes: 1

Views: 206

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726619

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.

Upvotes: 1

noelicus
noelicus

Reputation: 15055

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++){

Upvotes: 1

Related Questions