wonderingdev
wonderingdev

Reputation: 1181

Dealing with pointers and structures

I have a huge problem that I've tried solving in many different ways but could not find the solution.

What I must do is:

  1. create a function for introducing 2 sets
  2. another function for displaying these sets

It is required to use a structure, which components will be:

  1. the number of elements for respective set;

  2. a pointer(for storing the elements of these 2 sets);

    I do not know why, but when I execute the program (presented below),the second element of the first set isn't showing. Please, if you have time , can you help me find the problem. It's really frustrating when everything seems to be fine, and still the program isn't working. Thank you very much !!!

In header I have:

#ifndef L8_3H_H_
#define L8_3H_H_

struct Set
{
    unsigned int card;
    double *p[2];
};

typedef struct Set MULTIME;

MULTIME *introduce_data();
void showSet(MULTIME *m, int j);

#endif /* L8_3H_H_ */

In main I have:

    #include "L8_3h.h"
    #include <stdio.h>

int main( void )
{
    MULTIME *mult;


    mult = introduce_data();

    showSet(mult, 0);
    showSet(mult, 1);

return 0;
}

My functions are:

#include "L8_3h.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void showSet(MULTIME *m, int j)
{
    int i;



    if ( j == 0 )
    {
        printf("\nA = {");
    }else
    {
        printf("\nB = {");
    }

    for (i = 0; i < (m + j)->card; ++i)
    {
        printf("%lf", *((m + j)->p[j]+i));

        if (i != (m + j)->card - 1)
        {
            printf(", ");
        }
    }

    printf("}");
}


MULTIME *introduce_data()
{
    MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME));
    int i, j;


    for (i = 0; i < 2; ++i)
    {
        

        printf("\nIntroduce the number of elements of set %d", i + 1);
        scanf("%u", &(mult + i)->card);

        
       (mult+i)->p[i] = (double*)malloc(sizeof(double)*((mult+i)->card));

        
        printf("\nIntroduce the element of set %d\n", i+1);
        for (j = 0; j < (mult + i)->card; ++j)
        {
            scanf("%lf", ((mult + i)->p[i]+j));
 //It's interesting that when I put a printf right after  introducing the 
//element everything is fine(I get the right element)
        }
    

     }
    

    printf("\nHeres the problem");
    printf("\nThis should not be zero: %lf", *((mult + 0)->p[0]+1));
    
return mult;
}

Upvotes: 1

Views: 53

Answers (3)

wonderingdev
wonderingdev

Reputation: 1181

I hope it will be useful for others encountering the same problem.

Finally, thanks to Peter, I understood what was the problem. Peter noticed that I used the variable mult as an array of two elements of type MULTIME, while it was declared as a single-element variable.

So, after changing this:

MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME));

to this:

MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME)*2);

I've finally got the right result.

Upvotes: 0

Peter
Peter

Reputation: 36597

There are a number of problems within introduce_data() I can see on a quick look.

Firstly, converting the return value of malloc(), as in

MULTIME *mult = (MULTIME*)malloc(sizeof(MULTIME));

is unnecessary. Remove the (MULTIME *) conversion and ensure that there is an #include <stdlib.h> at the top of your code. Leaving out #include <stdlib.h> and using the conversion causes your code to have undefined behaviour. (The only exception is if your C compiler is actually a C++ compiler - in that case you need BOTH the #include <stdlib.h> and the conversion. Otherwise don't use the conversion.).

Second, the malloc() in allocates memory for mult as a single MULTIME. The loop then uses mult as if it is an array of two MULTIME. That falls off the end of the (dynamically allocated array). The behaviour is undefined.

Third, you are getting the mapping between array syntax and pointer syntax wrong. The statement

(mult+i)->p[i] = (double*)malloc(sizeof(double)*((mult+i)->card));

is functionally equivalent (with dropping the type conversion) to

mult[i].p[i] = malloc(sizeof(double)*(mult[i].card));

Similarly, the statement

scanf("%lf", ((mult + i)->p[i]+j));

is equivalent to

scanf("%lf", mult[i].p[i]+j);

Both of these are probably not what you intend.

The underlying concern is that you are not properly understanding how pointers work with arrays. You'll need to read your textbook more closely.

Upvotes: 1

pm100
pm100

Reputation: 50140

this seems wrong

struct Set
{
    unsigned int card;
    double *p[2];
};

you have a set with 2 lists of number. I think each set should have one list

struct Set
{
    unsigned int card;
    double *p;
};

things kind of go bad from there. You need to create 2 instances of Set and load data into each one. I would create a Load_Set function that takes a double list and returns a newly malloced Set

Upvotes: 1

Related Questions