471,851 Members | 979 Online

# 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.

Expand|Select|Wrap|Line Numbers
1. #include<iostream.h>
2. #include<conio.h>
3. long poweroften(int);     //to calculate power of 10
4.
5.
6. void main()
7. {
8. clrscr();
9.   unsigned long number=241526;   //to find the sum of digits as:
10.                  //2+4+1+5+2+6=20
11.   unsigned long   numstore=number; //to keep backup of number
12. unsigned long *quo =new unsigned long[];  //to calculate quotient
13. unsigned long *rem =new unsigned long[]; //to calc. remainder
14. int i,sum=0;
15. cout<<"\n the no. is: "<<number; //to display original number
16. /*cout<<"\n  quo is pointing to: "<<quo;
17. cout<<"\n rem is: "<<rem;*/
18.  for(i=0;number!=0;i++)
19.    {
20.      rem[i]=number%poweroften(i+1);   //finding remainder
21.
22.      number-=rem[i];  //substracting the rem from number
23.      quo[i] = rem[i]/poweroften(i);   //then calculating quotient
24.      cout<<"\n rem is: "<<(rem+i)<<"\n and quo is: "<<quo+i;
25.      //cout<<"\n rem is: rem["<<i<<"]"<<rem[i]<<"\t and QUO["<<i<<"]"<<quo[i];
26.      cout<<"\n  quo is pointing to: "<<quo+i;  //to get the address of quo elements
27.      cout<<"\n rem is pointing to: "<<rem+i;  //to get the address of rem elements
28.        getch();
29.   }
30.    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
31.                                        // remaining array values are not changed
32.   for(int j=0;j<i;j++)
33.      {
34.          cout<<"\n in the sum loop quo is pointing to: "<<quo;
35.          cout<<"\n adding "<<quo[j];  // to calculate the sum of quo[] array elements
36.          sum+=quo[j];
37.     }
38. cout<<"\n sum of number: "<<numstore<<" is: "<<sum;//sum is wrong since quo[0] is modified by the compiler
39. }
40. long poweroften(int i)
41. {
42.    unsigned long prod=1;
43.   for(int j=0;j<i;j++)
44.     {
45.     prod*=10;
46.     }
47.     return prod;
48. }
49.
50.
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.
Aug 23 '07 #1
14 4007
RRick
463 Expert 256MB
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];
Aug 23 '07 #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];
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,compact,huge etc.
Aug 24 '07 #3
Banfa
9,065 Expert Mod 8TB
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:
Expand|Select|Wrap|Line Numbers
1. int *p = new int[5];
2.
3. int count = 5;
4.
5. int *p2 = new int[count];
6.
Aug 24 '07 #4
No the syntax to dynamically allocate memory in C++ is

datatype pointer = new datatype[expression];

eg:
Expand|Select|Wrap|Line Numbers
1. int *p = new int[5];
2.
3. int count = 5;
4.
5. int *p2 = new int[count];
6.
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,please post the clarification if i am wrong.
Aug 24 '07 #5
Banfa
9,065 Expert Mod 8TB
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.
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).

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.
Aug 24 '07 #6
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(considering 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:
Expand|Select|Wrap|Line Numbers
1.
2. int *roll = new int[];   // pointer to store the starting address of mem loaction
3. cout<<"\n LOCATION POINTED BY ROLL IS: "<<roll;
4.                              // address stored in roll
5. // loop to store values in roll array
6.
7. for(int i=0;i<5;i++)
8.    {
9.      cout<<"NEXT LOCATION  pointed by roll is: "<<(roll+i);
10.     *(roll+i)=i+1;               //it stores the value in array elements
11.    }
12.
13. // now the loop to check values
14.
15. for(i=0;i<5;i++)
16.   {
17.     cout<<"roll is pointing to: "<<(roll+i)<<" and value in array is:"<<*   (roll+i)               // it displays the address along with the values
18. }
19.
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.
Aug 24 '07 #7
Banfa
9,065 Expert Mod 8TB
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.

Expand|Select|Wrap|Line Numbers
1. #include <vector>
2.
3. ...
4.
5. vector<int> rollno;
6.
7. rollno.push_back(6);
8. rollno.push_back(7);
9. rollno.push_back(8);
10.
This will handle all the memory allocation for you.
Aug 24 '07 #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.

Expand|Select|Wrap|Line Numbers
1. #include <vector>
2.
3. ...
4.
5. vector<int> rollno;
6.
7. rollno.push_back(6);
8. rollno.push_back(7);
9. rollno.push_back(8);
10.
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;
// 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.

--------------------------------------------------------------------------------
Aug 24 '07 #9
JosAH
11,448 Expert 8TB
For the new[]() operator you just need a primary expression which can be anything
as long as its value is an int value, so:

Expand|Select|Wrap|Line Numbers
1. int i= 41;
2. int* ip= new[i+1]; // <--- see? dynamically calculated
3. ip[0]= 42;
4. ip[1]= 54;
5.
The fact that your compiler accepts things like this:

Expand|Select|Wrap|Line Numbers
1. int* ip= new int[];
2.
... shows that the compiler is quite old and it mistakes int[] for *int; you should
upgrade to a later compiler version.

kind regards,

Jos
Aug 24 '07 #10
Banfa
9,065 Expert Mod 8TB
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

Expand|Select|Wrap|Line Numbers
1. int *p = new int[];
2.
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

Expand|Select|Wrap|Line Numbers
1. int *p = new int[10];
2.
If you do not now the amount of memory you need at compile time but can calculate it at run time use

Expand|Select|Wrap|Line Numbers
1. int array_size;
2.
3. // code to calculate array size
4.
5. int *p = new int[array_size];
6.
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.
Aug 24 '07 #11
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

Expand|Select|Wrap|Line Numbers
1. int *p = new int[];
2.
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

Expand|Select|Wrap|Line Numbers
1. int *p = new int[10];
2.
If you do not now the amount of memory you need at compile time but can calculate it at run time use

Expand|Select|Wrap|Line Numbers
1. int array_size;
2.
3. // code to calculate array size
4.
5. int *p = new int[array_size];
6.
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
Aug 24 '07 #12
JosAH
11,448 Expert 8TB
Look, this syntax

Expand|Select|Wrap|Line Numbers
1. int *p = new int[];
2.
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
Aug 24 '07 #13
Banfa
9,065 Expert Mod 8TB
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
Aug 24 '07 #14
JosAH
11,448 Expert 8TB
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
Aug 24 '07 #15