Thread: struct pointer

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    43

    struct pointer

    I'm having problems with my struct pointer (i think). the program is supposed to read in a string of numbers and convert them to int's in an array backwards. so if it reads in the string 123456789\0 the array will be 9,8,7,6,5,4,3,2,1. this way i can add and subtract them later. there are 2 problems I'm having: first when i read the string in and convert it to the array all of my arrays seem to have the same value as the last string i read in even though the other part of the struct is right, and second when i go to print the values in the struct the array values are wrong in the print function but not anywhere else. it seems to print out addresses rather then the values.

    the file format is as follows:

    1
    1 738493 382938

    the first line tells me how many operations there are.
    the fist number in each line tells me what operation to do... 1 is plus and 2 is minus
    the following 2 numbers are the strings that will be read and computed.

    any help would, well, help. i still need to get them to add and subtract but i think if i can fix this that will be easy.

    this is the code i hope you lot don't mind if i post it all it's 127 lines...

    Code:
    //big int test
    #include <stdio.h>
    #include <string.h>
    
    #define MAXSIZE 200
    
    struct integer* read_integer(char* stringInt);
    void print(struct integer *p);
    
    struct integer
    {
    	int* digits;
    	int size;
    };
    
    int main(void)
    {
        struct integer number[3];
        struct integer *p;
        char string_int[200];
        int i;
        int j;
        int file_lines;
        int test;
        
        FILE *fin;
        
        fin = fopen("bigint.txt","r");
        fscanf(fin, "%d ", &file_lines);
        
        for(i = 0; i < file_lines; i++)
        {
            fscanf(fin, "%d ", &test);
    
            for(j = 0; j < 2; j++)
            {
    
                fscanf(fin, "%s ", string_int);
    
            
                p = read_integer(string_int);
                
                number[j].size = p->size;
                
                //this part seems to be over written to all of 'number' not just
                //number[j] so all of my struct have the same number.digits array
                number[j].digits = p->digits;
    
            }
            p = &number[0];
            
            
            //this is the same code as in the print function
            //the print function here works correctly but the one in the print
            //  function is not
            printf("%d\n", p->size);
            for(i = 0; i < p->size; i++)
            {
                printf("%d\n", p->digits[i]);
            }
            
            print(p);
        }
        system("pause");
        return 0;
    }
    
    //Preconditions:    the first parameter is string that stores
    //                  only contains digits, doesn't start with
    //                  0, and is 200 or fewer characters long.
    //
    //Postconditions:   The function will read the digits of the
    //                  large integer character by character, 
    //                  convert them into integers and return a 
    //                  pointer to the appropriate struct integer.
    
    struct integer* read_integer(char* stringInt)
    {
        struct integer* big_number;
        int size;
        int number[200];
        int temp;
        int i;
        int j;
        
        size = strlen(stringInt);
        
        big_number = malloc(sizeof(struct integer));
        big_number->digits =(int*) malloc(sizeof(int) * size);
        
        for (i = size -1, j = 0; i >= 0 ; i--, j++)
        {
            number[i] = (int) (stringInt[j] - '0');
        }
        
        big_number->size = size;
        big_number->digits = number;
        
        //this is to check and see if the pointer has the right information
        printf("%d\n", big_number->size);
        for(i = 0; i < big_number->size; i++)
        {
            printf("%d\n", big_number->digits[i]);
        }
        
        return big_number;
    }
    
    //Preconditions:    p is a pointer to a big integer.
    //
    //Postconditions:   The big integer pointed to by p is 
    //                  printed out.
    //
    
    void print(struct integer *p)
    {
        int i;
        
        printf("%d\n", p->size);
        
        //this print loop prints out wrong even though the other one is right
        for(i = 0 ; i < p->size; i++)
        {
            printf("%d\n", p->digits[i]);
        }
    }

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    big_number->size = size;
    big_number->digits = number;

    several lines above it - you have allocated memory for digits array
    now - you loose this memory and switching to the local vaiable, that will be destoyed after the function exits.

    delete your local number array - and use the allocated with malloc big_number->digits array
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    43
    that helped a lot thank you . now it 'remembers' the different arrays and it prints them out in the print function; but, now in the print function it seems that the last number in my array is being turned into a 0. again i works out of the print function but when it passes to the function it seems to lose it.

    the only thing i would think is the malloc is wrong but it works outside of the function.

    I'll color what i changed

    Code:
    //big int test
    #include <stdio.h>
    #include <string.h>
    
    #define MAXSIZE 200
    
    struct integer* read_integer(char* stringInt);
    void print(struct integer *p);
    
    struct integer
    {
    	int* digits;
    	int size;
    };
    
    int main(void)
    {
        struct integer number[3];
        struct integer *p;
        struct integer *q; //i added this so i can print both arrays
        char string_int[200];
        int i;
        int j;
        int file_lines;
        int test;
        
        FILE *fin;
        
        fin = fopen("bigint.txt","r");
        fscanf(fin, "%d ", &file_lines);
        
        for(i = 0; i < file_lines; i++)
        {
            fscanf(fin, "%d ", &test);
    
            for(j = 0; j < 2; j++)
            {
    
                fscanf(fin, "%s ", string_int);
    
            
                p = read_integer(string_int);
                
                number[j].size = p->size;
                number[j].digits = p->digits;
                
                free(p->digits);
                free(p);
    
            }
            p = &number[0];
            q = &number[1];
            
            //this is the same code as in the print function
            //the print loop here works correctly but the one in the print
            //  function is not
            
            printf("%d\n", p->size);
            for(i = 0; i < p->size; i++)
            {
                printf("%d", p->digits[i]);
            }
            printf("\n");
            
            print(p);
            print(q);
        }
        system("pause");
        return 0;
    }
    
    //Preconditions:    the first parameter is string that stores
    //                  only contains digits, doesn't start with
    //                  0, and is 200 or fewer characters long.
    //
    //Postconditions:   The function will read the digits of the
    //                  large integer character by character, 
    //                  convert them into integers and return a 
    //                  pointer to the appropriate struct integer.
    
    struct integer* read_integer(char* stringInt)
    {
        struct integer* big_number;
        int i;
        int j;
        //i removed int number[200] and char temp
        
        big_number = malloc(sizeof(struct integer));
        big_number->size = strlen(stringInt);//i moved this here befor it was higher
        big_number->digits =(int*) malloc(sizeof(int) * big_number->size);
        
        for (i = big_number->size -1, j = 0; i >= 0 ; i--, j++)
        {
            big_number->digits[i] = (int) (stringInt[j] - '0');
        }
        
        //this is to check and see if the pointer has the right information
        printf("%d\n", big_number->size);
        for(i = 0; i < big_number->size; i++)
        {
            printf("%d", big_number->digits[i]);
        }
        printf("\n");
        
        return big_number;
    }
    
    //Preconditions:    p is a pointer to a big integer.
    //
    //Postconditions:   The big integer pointed to by p is 
    //                  printed out.
    //
    
    void print(struct integer *p)
    {
        int i;
        
        printf("%d\n", p->size);
        
        //this print loop prints out wrong even though the other one is right
        for(i = p->size -1 ; i >= 0; i--)//i changed the order so it prints the right way around
        {
            printf("%d", p->digits[i]);
        }
        printf("\n");
    }

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    free(p->digits);
    you just freed thee memory that is pointed by number[j].digits

    So later you are using the memory that is not yours anymore

    get rid of p and q in the main - you have number - array of structs.
    pass a corresponding struct into the readinteger function as a parameter (by pointer) and avoid allocating the
    big_number = malloc(sizeof(struct integer));


    you will work on the struct from main - and allocate only digits array as needed.

    and you get rid of confusing part

    number[j].size = p->size;
    number[j].digits = p->digits;

    because initialization of these members will be done by readinteger function - and you will know that you should not free digits array till you finish working with number[j] struct
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Sep 2008
    Posts
    43
    I guess i shouldn't have freed it. it works now but how do i get my function to be assigned to the struct directly without using a pointer? because this is an assignment and i have to use the function headers as is and i tried "&number[j] = readInteger(...);" the only thing that seems to work is a pointer to the struct.

    ... but please tell me it i'm missing something

    and thank you again!!

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What you are doing is fine. Just don't free p->digits. You can (and should) free p after you've made the copy of it's contents.
    [And you can do that simpler with number[j] = *p].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointer problem or so...
    By TL62 in forum C Programming
    Replies: 19
    Last Post: 01-12-2008, 11:45 PM
  2. Global Variables
    By Taka in forum C Programming
    Replies: 34
    Last Post: 11-02-2007, 03:25 AM
  3. "dereferencing pointer to incomplete type"
    By incognito54 in forum C Programming
    Replies: 2
    Last Post: 11-01-2005, 09:50 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM