user7355129
user7355129

Reputation:

Pointer to struct doesn't work properly?

typedef struct Spheres{
    int PositionX;
    int PositionY;
    int Color;
    int Mass;
    int Radius;
    int SpeedX;
    int SpeedY;
}Sphere;

char readFile(FILE *file,Sphere **totalSphere){
    int positionX,positionY,color,mass,radius,speedX,speedY,amountOfSpheres,i;
    fscanf(file,"%d",&amountOfSpheres);
    *totalSphere=malloc(amountOfSpheres*sizeof(Sphere));
    for (i=0;i<amountOfSpheres;i++){
        fscanf(file,"%d%d%d%d%d%d%d",&positionX,&positionY,&color,&mass,&radius,&speedX,&speedY);
        totalSphere[i]->PositionX=positionX;
        totalSphere[i]->PositionY=positionY;
        totalSphere[i]->Color=color;
        totalSphere[i]->Mass=mass;
        totalSphere[i]->Radius=radius;
        totalSphere[i]->SpeedX=speedX;
        totalSphere[i]->SpeedY=speedY;
    }
    printf("%d %d %d %d %d %d %d\n",totalSphere[0]->PositionX,totalSphere[0]->PositionY,totalSphere[0]->Color,totalSphere[0]->Mass,totalSphere[0]->Radius,totalSphere[0]->SpeedX,totalSphere[0]->SpeedY);
    printf("%d %d %d %d %d %d %d\n",totalSphere[1]->PositionX,totalSphere[1]->PositionY,totalSphere[1]->Color,totalSphere[1]->Mass,totalSphere[1]->Radius,totalSphere[1]->SpeedX,totalSphere[1]->SpeedY);
}


int main()
{
    FILE *file;
    Sphere *totalSphere;
    totalSphere=NULL;
    if ((file=fopen("input.txt","r"))!=NULL){
        if (readFile(file,&totalSphere)){
            printf("%d %d %d %d %d %d %d\n",totalSphere[0].PositionX,totalSphere[0].PositionY,totalSphere[0].Color,totalSphere[0].Mass,totalSphere[0].Radius,totalSphere[0].SpeedX,totalSphere[0].SpeedY);
            printf("%d %d %d %d %d %d %d\n",totalSphere[1].PositionX,totalSphere[1].PositionY,totalSphere[1].Color,totalSphere[1].Mass,totalSphere[1].Radius,totalSphere[1].SpeedX,totalSphere[1].SpeedY);
            fclose(file);
    return 0;
}

This is my code and this is the text file i'm reading from

The problem is that when the function readFile() ends, the values from totalSphere[1] are lost as you can see here but the values from totalSphere[0] are ok. Why is this happening?

Upvotes: 0

Views: 54

Answers (2)

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. corrects the problems listed in the comments to the question
  2. pays attention to the parameter types for functions like: malloc()
  3. properly checks for errors
  4. corrects several logic errors
  5. cleanly compiles
  6. separates the struct definition from the typedef for that struct
  7. properly cleans up before exiting due to errors
  8. passes the allocated memory to free() to avoid a memory leak
  9. documents why each header file is being included

And now the proposed code:

#include <stdio.h>   // printf(), fopen(), fclose(), perror(), fscanf(), fprintf()
#include <stdlib.h>  // exit(), EXIT_FAILURE, malloc(), free()

struct Spheres
{
    int PositionX;
    int PositionY;
    int Color;
    int Mass;
    int Radius;
    int SpeedX;
    int SpeedY;
};
typedef struct Spheres Sphere;


// prototypes
size_t readFile( FILE *file, Sphere **totalSphere );


size_t readFile( FILE *file, Sphere **totalSphere )
{
    int positionX;
    int positionY;
    int color;
    int mass;
    int radius;
    int speedX;
    int speedY;
    size_t amountOfSpheres;
    size_t i;

    if( 1 != fscanf( file, "%lu", &amountOfSpheres ) )
    {
        fprintf( stderr, "fscanf for number of spheres failed\n" );
        fclose( file );
        exit( EXIT_FAILURE );
    }

    *totalSphere = malloc( amountOfSpheres * sizeof(Sphere) );
    if( !totalSphere )
    {
        perror( "malloc failed" );
        fclose( file );
        exit( EXIT_FAILURE );
    }

    for ( i=0; i<amountOfSpheres; i++ )
    {
        if( 7 != fscanf(file, "%d%d%d%d%d%d%d",
            &positionX,
            &positionY,
            &color,
            &mass,
            &radius,
            &speedX,
            &speedY) )
        {
            fprintf( stderr, "fscanf to read fields of sphere failed\n" );
            fclose( file );
            free( totalSphere );
            exit( EXIT_FAILURE );
        }

        (*totalSphere)[i]->PositionX = positionX;
        (*totalSphere)[i]->PositionY = positionY;
        (*totalSphere)[i]->Color     = color;
        (*totalSphere)[i]->Mass      = mass;
        (*totalSphere)[i]->Radius    = radius;
        (*totalSphere)[i]->SpeedX    = speedX;
        (*totalSphere)[i]->SpeedY    = speedY;
    }

    for( size_t j=0; j<amountOfSpheres && j<2; j++ )
    {
        printf("%d %d %d %d %d %d %d\n",
            (*totalSphere)[j]->PositionX,
            (*totalSphere)[j]->PositionY,
            (*totalSphere)[j]->Color,
            (*totalSphere)[j]->Mass,
            (*totalSphere)[j]->Radius,
            (*totalSphere)[j]->SpeedX,
            (*totalSphere)[j]->SpeedY);
    }

    return amountOfSpheres;
}


int main( void )
{
    FILE *file =NULL;
    Sphere *totalSphere = NULL;

    if ( !(file = fopen("input.txt","r") ) )
    {
        perror( "fopen failed" );
        exit( EXIT_FAILURE );
    }

    size_t x= readFile( file, &totalSphere );

    for( size_t i=0; i<x && i<2; i++ )
    {
        printf("%d %d %d %d %d %d %d\n",
            totalSphere[i].PositionX,
            totalSphere[i].PositionY,
            totalSphere[i].Color,
            totalSphere[i].Mass,
            totalSphere[i].Radius,
            totalSphere[i].SpeedX,
            totalSphere[i].SpeedY);
    }

    fclose( file );
    free( totalSphere );
    return 0;
}

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320747

You got lost in levels of indirection, apparently. The array of Sphere objects that you allocated inside readFile is supposed to be accessed as (*totalSphere)[i]. E.g

for (i = 0; i < amountOfSpheres; i++) {
  fscanf(file, "%d%d%d%d%d%d%d", &positionX, &positionY, &color, &mass, &radius, &speedX, &speedY);
  (*totalSphere)[i].PositionX = positionX;
  (*totalSphere)[i].PositionY = positionY;
  ...

Your original version is incorrect.

The (*totalSphere)[i] syntax applies inside readFile, since totalSphere is Sphere ** there. In main you will access the received array the "regular" way - as totalSphere[i].

Upvotes: 1

Related Questions