memory overlap while dynamic initialization using new

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rohitkumar
    New Member
    • Aug 2007
    • 17

    memory overlap while dynamic initialization using new

    this is my code to calculate the sum of digits in a number
    for eg. 432567
    sum =4+3+2+5+6+7=27
    i 'm using turboc++ compiler from borland and i 'm runing my program on DOS.

    Code:
    #include<iostream.h>
    #include<conio.h>
    long poweroften(int);     //to calculate power of 10
    
    
    void main()
    {
    clrscr();
      unsigned long number=241526;   //to find the sum of digits as:
    				 //2+4+1+5+2+6=20
      unsigned long   numstore=number; //to keep backup of number
    unsigned long *quo =new unsigned long[];  //to calculate quotient
    unsigned long *rem =new unsigned long[]; //to calc. remainder
    int i,sum=0;
    cout<<"\n the no. is: "<<number; //to display original number
    /*cout<<"\n  quo is pointing to: "<<quo;
    cout<<"\n rem is: "<<rem;*/
     for(i=0;number!=0;i++)
       {
         rem[i]=number%poweroften(i+1);   //finding remainder
    
         number-=rem[i];  //substracting the rem from number
         quo[i] = rem[i]/poweroften(i);   //then calculating quotient
         cout<<"\n rem is: "<<(rem+i)<<"\n and quo is: "<<quo+i;
         //cout<<"\n rem is: rem["<<i<<"]"<<rem[i]<<"\t and QUO["<<i<<"]"<<quo[i];
         cout<<"\n  quo is pointing to: "<<quo+i;  //to get the address of quo elements
         cout<<"\n rem is pointing to: "<<rem+i;  //to get the address of rem elements
           getch();
      }
       cout<<"\n and quo[0] is: "<<quo[0]; //it should store 6(the first remainder) but it's value is: 1000 that is rem[2]'s value
                                           // remaining array values are not changed
      for(int j=0;j<i;j++)
         {
             cout<<"\n in the sum loop quo is pointing to: "<<quo;
             cout<<"\n adding "<<quo[j];  // to calculate the sum of quo[] array elements
             sum+=quo[j];
        }
    cout<<"\n sum of number: "<<numstore<<" is: "<<sum;//sum is wrong since quo[0] is modified by the compiler
    }
    long poweroften(int i)
    {
       unsigned long prod=1;
      for(int j=0;j<i;j++)
        {
        prod*=10;
        }
        return prod;
    }
    quo[0] value is getting overlapped by rem[2]
    and if the number is large(for eg- 2146898787) quo[1] and quo[2] are also overlapped by rem[3] and rem[4].
    i don't know why it's happening.
  • RRick
    Recognized Expert Contributor
    • Feb 2007
    • 463

    #2
    You're not allocating enough space for quo and rem. You need to pick some number that is greating than the max number of digits you expect to process.

    My compiler won't let me say new ... [ ] without a number in between the [ and ]. I'm not sure what is being created, but its not enough. Since you're just using the variables locally, you can define them locally. For example: int quo[20];

    Comment

    • rohitkumar
      New Member
      • Aug 2007
      • 17

      #3
      Originally posted by RRick
      You're not allocating enough space for quo and rem. You need to pick some number that is greating than the max number of digits you expect to process.

      My compiler won't let me say new ... [ ] without a number in between the [ and ]. I'm not sure what is being created, but its not enough. Since you're just using the variables locally, you can define them locally. For example: int quo[20];
      i think the syntax to allocate memeory to an array dynamically is as follows:
      datatype pointer = new datatype[];
      eg:
      int *p = new int[];
      if i am allocating memory dynamically i think the size is not fixed, it is always decided at run time so, i can't put a no. inside [].
      we can access the dynamically allocated memory using pointer p;.
      about quo[20],this is allocation of memory at compile time.i want to use a variable allocated at the run time which in turn will be dependent on value of the number at run time.

      i think it is related to the memory model we are using for eg: tiny,small,comp act,huge etc.

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        Originally posted by rohitkumar
        datatype pointer = new datatype[];
        eg:
        int *p = new int[];
        No the syntax to dynamically allocate memory in C++ is

        datatype pointer = new datatype[expression];

        eg:
        Code:
        int *p = new int[5];
        
        int count = 5;
        
        int *p2 = new int[count];

        Comment

        • rohitkumar
          New Member
          • Aug 2007
          • 17

          #5
          Originally posted by Banfa
          No the syntax to dynamically allocate memory in C++ is

          datatype pointer = new datatype[expression];

          eg:
          Code:
          int *p = new int[5];
          
          int count = 5;
          
          int *p2 = new int[count];
          then how come this is a dynamic memory allocation if i have to determine the size at run time only.
          new is used for allocating memory at runtime depending upon the number of elements and it returns the starting address of heap memory.
          my compiler is ok with this type of syntax
          int *p = new int[]
          now the integer array will be created at run time and any no. of elements will be added to it,till the heap memory gets exhausted.
          this is what i interpret,pleas e post the clarification if i am wrong.
          thanks in advance.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Originally posted by rohitkumar
            then how come this is a dynamic memory allocation if i have to determine the size at run time only.
            It is dynamic because you can determin the size at runtime if you desire or it can be fixed at compile time.
            Originally posted by rohitkumar
            new is used for allocating memory at runtime depending upon the number of elements and it returns the starting address of heap memory.
            my compiler is ok with this type of syntax
            int *p = new int[]
            Yes exactly but in this syntax you don't provide it with the number of required elements, this generates a request for 0 bytes of memory (if it compiles).

            Originally posted by rohitkumar
            now the integer array will be created at run time and any no. of elements will be added to it,till the heap memory gets exhausted.
            No memory is only allocated from the heap in response to an explicit call to new or malloc or calloc or realloc. You allocate 0 bytes of memory and then write multiple values to that unallocated block. You are creating memory corruptions and running a very real risk of a segmentation fault.

            Comment

            • rohitkumar
              New Member
              • Aug 2007
              • 17

              #7
              another question

              Originally posted by Banfa
              It is dynamic because you can determin the size at runtime if you desire or it can be fixed at compile time.
              Yes exactly but in this syntax you don't provide it with the number of required elements, this generates a request for 0 bytes of memory (if it compiles).

              No memory is only allocated from the heap in response to an explicit call to new or malloc or calloc or realloc. You allocate 0 bytes of memory and then write multiple values to that unallocated block. You are creating memory corruptions and running a very real risk of a segmentation fault.
              Thanks for the detailed reply. now the picture is somewhat clear to me. still one issue is remaining, if ever, i have to use an array whose size cannot be determined at compile time suppose to store student rollnos,then should i use the syntax
              int *rollno= new int[100];
              considering that max expected no. of students is 100. this will store the starting address of the memory loaction in rollno and provide me with 200 bytes of memory(consider ing int of size 2 bytes on the machine) but i suppose this is wastage of some memory if the no. of students is less than 100.what in the case if number of students >100; i think the pointer will write to some memory locations that will result in some error in my program(if at all those locations are used by my other variables).
              there must be some way to allocate memory at the run time and its size must vary with the addition of new values in array. its giving me a really hard time.
              also please suggest me a good online tutorial on pointers and memory allocations.
              another question is if the compiler does not allocate any memory(
              according to you it will return an address and 0 bytes of memory)
              for the following syntax;
              int *roll=new int[];
              then howcome my compiler always shows adderess pointed to by
              roll+i. for eg.
              if i use the following code:
              Code:
              int *roll = new int[];   // pointer to store the starting address of mem loaction
              cout<<"\n LOCATION POINTED BY ROLL IS: "<<roll; 
                                           // address stored in roll
              // loop to store values in roll array
              
              for(int i=0;i<5;i++)
                 {
                   cout<<"NEXT LOCATION  pointed by roll is: "<<(roll+i);
                  *(roll+i)=i+1;               //it stores the value in array elements
                 }
              
              // now the loop to check values
              
              for(i=0;i<5;i++)
                { 
                  cout<<"roll is pointing to: "<<(roll+i)<<" and value in array is:"<<*   (roll+i)               // it displays the address along with the values  
              }
              according to u if the memory of 0 bytes is returned how come i m able to store
              values in the array.
              this pointer thing is really bugging me.but i wanna master this pointer monster.i need ur help.
              Last edited by rohitkumar; Aug 24 '07, 02:16 PM. Reason: one more question

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                The trick is rather than use arrays, which is considered poor form in C++ use one of the STL container classes. In this case a vector would probably be the class of choice.

                Code:
                #include <vector>
                
                ...
                
                vector<int> rollno;
                
                rollno.push_back(6);
                rollno.push_back(7);
                rollno.push_back(8);
                This will handle all the memory allocation for you.

                Comment

                • rohitkumar
                  New Member
                  • Aug 2007
                  • 17

                  #9
                  Originally posted by Banfa
                  The trick is rather than use arrays, which is considered poor form in C++ use one of the STL container classes. In this case a vector would probably be the class of choice.

                  Code:
                  #include <vector>
                  
                  ...
                  
                  vector<int> rollno;
                  
                  rollno.push_back(6);
                  rollno.push_back(7);
                  rollno.push_back(8);
                  This will handle all the memory allocation for you.
                  according to you it will return an address and 0 bytes of memory)
                  for the following syntax;
                  int *roll=new int[];
                  then howcome my compiler always shows adderess pointed to by
                  roll+i. for eg.
                  if i use the following code:

                  Code: ( text )
                  int *roll = new int[]; // pointer to store the starting address of mem loaction
                  cout<<"\n LOCATION POINTED BY ROLL IS: "<<roll;
                  // address stored in roll
                  // loop to store values in roll array

                  for(int i=0;i<5;i++)
                  {
                  cout<<"NEXT LOCATION pointed by roll is: "<<(roll+i) ;
                  *(roll+i)=i+1; //it stores the value in array elements
                  }

                  // now the loop to check values

                  for(i=0;i<5;i++ )
                  {
                  cout<<"roll is pointing to: "<<(roll+i) <<" and value in array is:"<<* (roll+i) // it displays the address along with the values
                  }


                  according to u if the memory of 0 bytes is returned how come i m able to store
                  values in the array.
                  this pointer thing is really bugging me.but i wanna master this pointer monster.i need ur help.

                  --------------------------------------------------------------------------------

                  Comment

                  • JosAH
                    Recognized Expert MVP
                    • Mar 2007
                    • 11453

                    #10
                    For the new[]() operator you just need a primary expression which can be anything
                    as long as its value is an int value, so:

                    [code=cpp]
                    int i= 41;
                    int* ip= new[i+1]; // <--- see? dynamically calculated
                    ip[0]= 42;
                    ip[1]= 54;
                    [/code]

                    The fact that your compiler accepts things like this:

                    [code=cpp]
                    int* ip= new int[];
                    [/code]

                    ... shows that the compiler is quite old and it mistakes int[] for *int; you should
                    upgrade to a later compiler version.

                    kind regards,

                    Jos

                    Comment

                    • Banfa
                      Recognized Expert Expert
                      • Feb 2006
                      • 9067

                      #11
                      Originally posted by rohitkumar
                      according to u if the memory of 0 bytes is returned how come i m able to store
                      values in the array.
                      I didn't say 0 bytes where returned, I said it generated a request for 0 bytes. It is not unknow for the memory manager to add extra bytes to the requested number in order to store information about the block of data allocated.

                      Look, this syntax

                      [code=cpp]
                      int *p = new int[];
                      [/code]

                      is wrong, someone has said it doesn't compile for them, on my system it generates a request for 0 bytes the behaviour is clearly platform dependent (or undefined which is worst). If you write to the pointer returned at some point you will undoubtedly corrupt the program memory.

                      Just don't use it.

                      If you know the amount of memory you require at compile time use the syntax

                      [code=cpp]
                      int *p = new int[10];
                      [/code]

                      If you do not now the amount of memory you need at compile time but can calculate it at run time use

                      [code=cpp]
                      int array_size;

                      // code to calculate array size

                      int *p = new int[array_size];
                      [/code]

                      However better still do not use an array at all, they are not really an object orientated approach to programming. Instead use an STL container class like the vector.

                      Comment

                      • rohitkumar
                        New Member
                        • Aug 2007
                        • 17

                        #12
                        Originally posted by Banfa
                        I didn't say 0 bytes where returned, I said it generated a request for 0 bytes. It is not unknow for the memory manager to add extra bytes to the requested number in order to store information about the block of data allocated.

                        Look, this syntax

                        [code=cpp]
                        int *p = new int[];
                        [/code]

                        is wrong, someone has said it doesn't compile for them, on my system it generates a request for 0 bytes the behaviour is clearly platform dependent (or undefined which is worst). If you write to the pointer returned at some point you will undoubtedly corrupt the program memory.

                        Just don't use it.

                        If you know the amount of memory you require at compile time use the syntax

                        [code=cpp]
                        int *p = new int[10];
                        [/code]

                        If you do not now the amount of memory you need at compile time but can calculate it at run time use

                        [code=cpp]
                        int array_size;

                        // code to calculate array size

                        int *p = new int[array_size];
                        [/code]

                        However better still do not use an array at all, they are not really an object orientated approach to programming. Instead use an STL container class like the vector.
                        thanks for the clarification.
                        could u suggest any good tutorial on pointers.
                        regards
                        rohit

                        Comment

                        • JosAH
                          Recognized Expert MVP
                          • Mar 2007
                          • 11453

                          #13
                          Originally posted by Banfa
                          Look, this syntax

                          [code=cpp]
                          int *p = new int[];
                          [/code]

                          is wrong, someone has said it doesn't compile for them, on my system it generates a request for 0 bytes the behaviour is clearly platform dependent
                          I don't understand this; according to my version of the latest C++ syntax it
                          should be illegal: a 'primary-expression' is wanted there by the parser. Which
                          basically means any expression but not just nothing at all.

                          I do realize that C++'s syntax is a large beast with a lot of context sensitive
                          stuff in it ...

                          kind regards,

                          Jos

                          Comment

                          • Banfa
                            Recognized Expert Expert
                            • Feb 2006
                            • 9067

                            #14
                            Originally posted by JosAH
                            I don't understand this; according to my version of the latest C++ syntax it
                            should be illegal: a 'primary-expression' is wanted there by the parser. Which
                            basically means any expression but not just nothing at all.
                            Does this becomes easier to understand when I tell you that I am using a Microsoft compiler?

                            I find it easier to imagine that Microsoft have produce a compiler that is no-comforming in this regard than you being wrong Jos :D

                            Comment

                            • JosAH
                              Recognized Expert MVP
                              • Mar 2007
                              • 11453

                              #15
                              Originally posted by Banfa
                              Does this becomes easier to understand when I tell you that I am using a Microsoft compiler?

                              I find it easier to imagine that Microsoft have produce a compiler that is no-comforming in this regard than you being wrong Jos :D
                              I checked it again but a 'primary-expression' is expected between those two
                              square brackets (read: any sensible expression). Shame on MS and shame on
                              that old turbo C++ compiler which the OP uses. I vaguely remember that those
                              old compilers erroneously took a T[] for a *T where no value context was around.
                              That might explain it ... the GNU compiler suite has it right again though.

                              kind regards,

                              Jos

                              Comment

                              Working...