Thread: Dynamically Allocated Arrays- my pointers are a mess

  1. #1
    Registered User
    Join Date
    Jan 2010
    Posts
    103

    Dynamically Allocated Arrays- my pointers are a mess

    Hey, I have a homework assignment, bigint.txt

    the program will read a file bigint.txt and the first number will be n, which is how many lines to read, then each line will have 3 numbers; the first number is the operand, 1 for plus, 0 for minus; the next two numbers are the numbers to do the operands on; its pretty basic but this is where it gets complicated and is messing me up

    i need to create a struct

    struct integer {an array of ints, an int}

    so two numbers, two integers; each number will be stored in the array BACKWARDS

    so for the number 126

    array[0]=6; array[1]=2; array[2]=1; this is so i can write methods add,subtract easier, i guess; however in my homework assignment, my add/subtract methods are a MESS

    I cannot find what is wrong with my homework; when i make my program printf() all my steps and changes, crazy things happen; sometimes they'll point to an address and print it out, other times they print out the right answer (when i never even changed the code, just reran right after)

    Help would be apprecited please! The add method runs fine with two single digit numbers, but when a number has two digits, my program crashes, also, when the resulting struct increases in digit number, it doesnt save the extra digit (for example 86+31 gives me 17, not 117); the subtract method is supposed to subtract the smaller from bigger, but it always just switches regardless of my if() else()

    This is my first program ever dealing with all this junk, so i apologize for the mess

    Code:
    //Jason Shih
    //Big Integers
    //January 25, 2010
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX_LEN 201
    
    struct integer {
           int* digits;
           int size;
    };
    
    struct integer* read_integer(char* stringInt);
    void print(struct integer *p);
    struct integer* add(struct integer *p, struct integer *q);
    struct integer* subtract(struct integer *p, struct integer *q);
    int compare(struct integer *p, struct integer *q);
    
    int main() {
        FILE *read;
        char string_one[MAX_LEN], string_two[MAX_LEN];
        int steps, i, operation;
        struct integer *p;
        struct integer *q;
        struct integer *ans;
        read=fopen("bigint.txt","r");
        fscanf(read,"%d",&steps);
        for(i=0;i<steps;i++) {
           printf("i = %d, step=%d\n", i, steps);
           fscanf(read,"%d%s%s",&operation,string_one,string_two);
           p=read_integer(string_one);
           q=read_integer(string_two);
           //print addition equation
           if(operation==1) {
              print(p);
              printf("+");
              print(q);
              printf("= ");
              ans=add(p,q);
              print(ans);
              printf("\n");
              system("PAUSE");
              }
           else {
                //print subtraction equation
                if(compare(p,q)==1) {
                   print(p);
                   printf("-");
                   print(q);
                   printf("= ");
                }
                else {
                   print(q);
                   printf("-");
                   print(p);
                   printf("= ");
                }
                ans=subtract(p,q);
                print(ans);
                printf("\n");
           }
           free(p->digits);
           free(p);
           free(q->digits);
           free(q);
           free(ans->digits);
           free(ans);
        }
        fclose(read);
        system("PAUSE");
        return 0;
    }
    
    //create an integer using a string of ints
    
    struct integer* read_integer(char* stringInt) {
    
           struct integer* c;
           int string_size=strlen(stringInt);
           c = (struct integer*)malloc(sizeof(struct integer));
           c->size=string_size;
           c->digits=(int*)malloc(sizeof(int)*c->size);
           int i;
           for(i=0;i<string_size;i++) {
              c->digits[i]=stringInt[string_size-1-i]-'0';
           }
           printf("\n");
           print(c);
           printf("\n");
           return c;
    }
    
    //prints integer in correct direction
    void print(struct integer *p) {
         int i;
         for(i=p->size-1;i>=0;i--) {
            printf("%d",p->digits[i]);                    
         }
    }
    
    //make integer c same size as bigger integer p or q; then add them together
    //and return c;
    struct integer* add(struct integer *p, struct integer *q) {
           struct integer* c;
           struct integer* bigger;
           //trying to make it bigger so it can store that extra digit
           c=(struct integer*)malloc(sizeof(struct integer)*2);
           int comp=compare(p,q);
           if(comp>=0)
              c->size=p->size;
           else
              c->size=q->size;
           int i=0;
           for(i=0;i<c->size;i++) {
              if(p->digits[i]+q->digits[i]<10)
                 c->digits[i]=p->digits[i]+q->digits[i];
              //result>10 so carry over to the next digit
              else {
                 int temp=p->digits[i]+q->digits[i];
                 temp %=10;
                 c->digits[i]=temp;
                 printf("\n\n");
                 print(p);
                 printf("\n\n");
                 print(q);
                 printf("\n\n");
                 printf("%d",c->digits[i]);
              }
           }
           printf("\n"); 
           printf("\n");
           return c;
           }
    
    //find which is bigger, then subtract the smaller one from the bigger one
    struct integer* subtract(struct integer *p, struct integer *q) {
                struct integer* c;
                c=(struct integer*) malloc(sizeof(struct integer));
                int i;
                int comp=compare(p,q);
                //whichever one is bigger is the one subtracted from;
                //same operation;
                if(comp==1) {
                   c->size=p->size;
                   for(i=0;i<c->size;i++) {
                      if(p->digits[i]>q->digits[i])
                         c->digits[i]=p->digits[i]-q->digits[i];
                      else if(p->digits<q->digits[i]) {
                         c->digits[i]=q->digits[i]-p->digits[i];
                         p->digits[i]-=1;
                      }
                   }
                }
                else if(comp==-1) {
                   c->size=q->size;
                   for(i=0;i<c->size;i++) {
                      if(q->digits[i]>p->digits[i])
                         c->digits[i]=q->digits[i]-p->digits[i];
                      else if(q->digits<p->digits[i]) {
                         c->digits[i]=p->digits[i]-q->digits[i];
                         q->digits[i]-=1;
                      }
                   }
                }
                else {
                   c->size=0;
                   c->digits=0;  
                }         
                return c;
    }
    
    //return 1 if p>q, 0 if p==q, -1 if p<q
    int compare(struct integer *p, struct integer *q) {
           //check to see which one is bigger;
           if(p->size>q->size)
              return 1;
           else if(p->size<q->size)
              return -1;
           //if equal sizes, check to see which digits are bigger from the 
           //more important digits
           else {
                int i;
                for(i=q->size;i>0;i++) {
                   if(p->digits[i]>q->digits[i])
                      return 1;
                   else if(p->digits[i]<q->digits[i])
                      return -1;
                }
           }
           return 0;
    }
    Last edited by Soulzityr; 01-26-2010 at 07:51 PM. Reason: adding text

  2. #2
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    can no one help me? its due in 2:30 hours and I have no clue how to fix this; every time i try to change the code somehow the output gets even worse.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Pick one problem at a time, focus on it, ask more specific questions, use printf to check what's happening, and when you post again, show an example of the one specific problem together with the debugging output from printf.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Jason, do you have to use structs with this assignment?

    I've got to go eat but I'll take a look at it when I get back.

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    output:

    Code:
    i = 0, step=6
    4+5=
    
    9
    Press any key to continue...
    i = 1, step=6
    13+8=
    
    13 //i made it print p to check its value
    
    8 //i made it print q to check its value
    
    1 //this is printing out what's currently digits[i] in the for loop, 3+8 =11 and digits[i]=11%10; the tens place is supposed to get carried over
    
    13 //printing p again, running twice because 13 has two digits, thus it will add tens place now
    
    8//printing q
    
    3//gives me 3 for the tens place
    
    31//printing the total
    therefore without these prints to check, it is saying 13+8=31. Also, after this, my program stops, even though i have more instructions for it after. The parts of my code involved are in the main() and the add(), and while i dont think its the problem its also connected to read_integer() and print()

    --on a side note, my add function also cannot increase the digit size

    for example, when 86+31, the answer should be 117, but since the c->size is equal to p->size or q->size, it only gives 17. I tried making p->size+1 and such, but that doesnt work, apparently. it screws it up and all of a sudden i end up with the address as an answer
    Last edited by Soulzityr; 01-26-2010 at 08:50 PM.

  6. #6
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    Quote Originally Posted by Adak View Post
    Jason, do you have to use structs with this assignment?

    I've got to go eat but I'll take a look at it when I get back.
    Lol do you know my name from my program header??

    And yes, i must have

    Code:
    struct integer {
           int* digits;
           int size;
    };
    
    //must store the number backwards

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I think you should write a short, separate program where main() simply declares two int arrays containing hardcoded values, a "big number" in the backward form you describe.

    Then transplant your add function in (so the program just has main, and the add function), and add the numbers using the function. This will allow you to rule out any number of complications, and once that function works in a stand-alone context, you know that it can be put back into your project. Clearly, you have too much going on and have been overwhelmed

    I know this sounds rough -- like it is a big waste of time, doing all this extra typing, etc. -- but sometimes problems are solved faster thru action than contemplation. As a bonus, doing this will also make it much easier for others to analyse the problem.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    yes i believe i am overwhelmed Q_Q the combined crashing errors of both subtract and add functions have completel destroyed my self-esteem in my programming skills lol; but i have sort of started doing your advice, in that i have completely // -<whatever this is my subtract orders, so that function isnt even being used right now; it has like 30 problems of its own

    im not quite sure what you mean; i should have another source file where i take 2 int arrays already declared and then make a function that tinkers with it? will it work the same, even if i use the arrays themselves instead of the pointers? i remember learning that arrays basically use pointers right? heheh, sorry, i am a student who's new to programming Q_Q

    i will try to write a separate program to test a new add function and bring it back here if i have further problems with it, thanks >.< unfortunately, i think my logic in the functions have lots of problems as well...thanks for the advice on how to attack this problem for now though

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    If it's okay, I do have a specific question regarding my add() function;

    I want to increase the size of memory allocated to my struct integer c so that it can store an extra digit more than it used to;

    what command do i use to expand more memory?

    i tried using malloc(sizeof(struct integer)+1); or something...but i didnt think that'd work to begin with

    this little breather would be nice, please Q_Q i cannot find it online ,they all say to use realloc and i dont know what to use as the expander size for that either

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Here's an idea w/ realloc:
    Code:
    c->size++;
    c->digits = realloc(c->digits,c->size);
    It's the array inside the struct you want to resize!

    WRT the test program, write it so the add function can work exactly as it is supposed to, but no more complicated than that. If you need the whole struct, use the whole struct, and malloc digits, then assign them a value. You could also do this:
    Code:
    int ray[5] = { 1, 2, 3, 4, 5 }
    struct integer *c = malloc...;
    c->digits = ray;
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    ahhh i see what i was doing wrong!!~!!!! changing the size value in the integer doesn't change the size of memory allocated!! thank you!! as for my test program, i did indeed write a new struct integer for it and ahaha...when i added it

    13+8 =

    91097021
    ---

    still trying to solve this problem but at least im starting to get somewhere! thanks very much, i was frozen at that point for almost two hours not knowing how to possibly get started >.<

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Oh by the way, that should have been "realloc(c->digits, c->size*sizeof(int))" in my last post, whoops.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    In the subtract function, you have two lines of code that are missing the [i] part. It should look like this:

    Code:
                      if(q->digits[i]>p->digits[i])
                         c->digits[i]=q->digits[i]-p->digits[i];
                      else if(q->digits[i] < p->digits[i]) {
                         c->digits[i]=p->digits[i]-q->digits[i];
                         q->digits[i]-=1;
                      }
    I believe it was the two in red, above. Not positive because I fixed them in a rush.

    Get a chance, please post your most recent version of the program.
    Last edited by Adak; 01-26-2010 at 09:53 PM.

  14. #14
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    hmm i did have it fixed in mine, but thanks for the catch lol;

    Code:
    //Jason Shih
    //Big Integers
    //January 25, 2010
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MAX_LEN 201
    
    struct integer {
           int* digits;
           int size;
    };
    
    struct integer* read_integer(char* stringInt);
    void print(struct integer *p);
    struct integer* add(struct integer *p, struct integer *q);
    struct integer* subtract(struct integer *p, struct integer *q);
    int compare(struct integer *p, struct integer *q);
    
    int main() {
        FILE *read;
        char string_one[MAX_LEN], string_two[MAX_LEN];
        int steps, i, operation;
        struct integer *p;
        struct integer *q;
        struct integer *ans;
        read=fopen("bigint.txt","r");
        fscanf(read,"%d",&steps);
        for(i=0;i<steps;i++) {
           printf("i = %d, step=%d\n", i, steps);
           fscanf(read,"%d%s%s",&operation,string_one,string_two);
           p=read_integer(string_one);
           q=read_integer(string_two);
           //print addition equation
           if(operation==1) {
              print(p);
              printf("+");
              print(q);
              printf("= ");
              ans=add(p,q);
              print(ans);
              printf("\n");
              system("PAUSE");
              }
           else {
                //print subtraction equation
                if(compare(p,q)==1) {
                   print(p);
                   printf("-");
                   print(q);
                   printf("= ");
                }
                else {
                   print(q);
                   printf("-");
                   print(p);
                   printf("= ");
                }
                ans=subtract(p,q);
                print(ans);
                printf("\n");
           }
           free(p->digits);
           free(p);
           free(q->digits);
           free(q);
           free(ans->digits);
           free(ans);
        }
        fclose(read);
        system("PAUSE");
        return 0;
    }
    
    //create an integer using a string of ints
    
    struct integer* read_integer(char* stringInt) {
    
           struct integer* c;
           int string_size=strlen(stringInt);
           c = (struct integer*)malloc(sizeof(struct integer));
           c->size=string_size;
           c->digits=(int*)malloc(sizeof(int)*c->size);
           int i;
           for(i=0;i<string_size;i++) {
              c->digits[i]=stringInt[string_size-1-i]-'0';
           }
           return c;
    }
    
    //prints integer in correct direction
    void print(struct integer *p) {
         int i;
         for(i=p->size-1;i>=0;i--) {
            printf("%d",p->digits[i]);                    
         }
    }
    
    //make integer c same size as bigger integer p or q; then add them together
    //and return c;
    struct integer* add(struct integer *p, struct integer *q) {
           struct integer* c;
           struct integer* bigger;
           //trying to make it bigger so it can store that extra digit
           c=(struct integer*)malloc(sizeof(struct integer));
           int comp=compare(p,q);
           if(comp>=0)
              c->size=p->size;
           else
              c->size=q->size;
           int i=0;
           //c->size++;
           //c->digits=realloc(c->digits,c->size);
           for(i=0;i<c->size;i++) {
              if(p->digits[i]+q->digits[i]<10)
                 c->digits[i]=p->digits[i]+q->digits[i];
              //result>10 so carry over to the next digit
              else {
                 int temp=p->digits[i]+q->digits[i];
                 temp %=10;
                 c->digits[i]=temp;
                 
                 //attempt at solving the carry problem
                 
                 c->digits[i+1]=p->digits[i+1]+q->digits[i+1]+1;
                 i++;
                 
                 //sequence checker
                 
                 printf("\n\n");
                 print(p);
                 printf("\n\n");
                 print(q);
                 printf("\n\n");
                 printf("%d",c->digits[i]);
              }
           }
           printf("\n"); 
           printf("\n");
           return c;
           }
    
    //find which is bigger, then subtract the smaller one from the bigger one
    struct integer* subtract(struct integer *p, struct integer *q) {
                struct integer* c;
                c=(struct integer*) malloc(sizeof(struct integer));
                int i;
                int comp=compare(p,q);
                //whichever one is bigger is the one subtracted from;
                //same operation;
                if(comp==1) {
                   c->size=p->size;
                   for(i=0;i<c->size;i++) {
                      if(p->digits[i]>q->digits[i])
                         c->digits[i]=p->digits[i]-q->digits[i];
                      else if(p->digits[i]<q->digits[i]) {
                         c->digits[i]=q->digits[i]-p->digits[i];
                         p->digits[i]-=1;
                      }
                   }
                }
                else if(comp==-1) {
                   c->size=q->size;
                   for(i=0;i<c->size;i++) {
                      if(q->digits[i]>p->digits[i])
                         c->digits[i]=q->digits[i]-p->digits[i];
                      else if(q->digits<p->digits[i]) {
                         c->digits[i]=p->digits[i]-q->digits[i];
                         q->digits[i]-=1;
                      }
                   }
                }
                else {
                   c->size=0;
                   c->digits=0;  
                }         
                return c;
    }
    
    //return 1 if p>q, 0 if p==q, -1 if p<q
    int compare(struct integer *p, struct integer *q) {
           //check to see which one is bigger;
           if(p->size>q->size)
              return 1;
           else if(p->size<q->size)
              return -1;
           //if equal sizes, check to see which digits are bigger from the 
           //more important digits
           else {
                int i;
                for(i=q->size;i>0;i++) {
                   if(p->digits[i]>q->digits[i])
                      return 1;
                   else if(p->digits[i]<q->digits[i])
                      return -1;
                }
           }
           return 0;
    }

  15. #15
    Registered User
    Join Date
    Jan 2010
    Posts
    103
    lol only twenty minutes; i made extremely minor changes trying to solve it; haha i doubt i can complete this, blahh; thanks for the help anyways you two

    i'll still be trying to perfect this after tonight's due date if you're willing

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamically allocated array
    By dre in forum C Programming
    Replies: 17
    Last Post: 08-13-2009, 06:57 PM
  2. swap dynamically allocated arrays
    By myle in forum C Programming
    Replies: 9
    Last Post: 05-18-2008, 09:04 AM
  3. Dynamically allocated size
    By maverickbu in forum C++ Programming
    Replies: 12
    Last Post: 06-26-2007, 01:16 PM
  4. Destructors in dynamically allocated arrays
    By frenchfry164 in forum C++ Programming
    Replies: 1
    Last Post: 11-28-2003, 11:26 PM
  5. Pointers, arrays , functions
    By sballew in forum C Programming
    Replies: 19
    Last Post: 09-16-2001, 11:12 PM