problem from tutorial

Pages: 1234
hello there, i've been trying 2 learn c++ & was following the tutorials in this site, i'm stuck with the dynamic memory section. the following code is from the example :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// rememb.o.matic 
#include <iostream> 
#include <new> 
using namespace std; 
 
int main () 
{ 
  int i,n; 
  int * p; 
  cout << "How many numbers would you like to type? "; 
  cin >> i; 
  p= new (nothrow) int[i]; 
  if (p == 0) 
    cout << "Error: memory could not be allocated"; 
  else 
  { 
    for (n=0; n<i; n++) 
    { 
      cout << "Enter number: "; 
      cin >> p[n]; 
    } 
    cout << "You have entered: "; 
    for (n=0; n<i; n++) 
      cout << p[n] << ", "; 
    delete[] p; 
  } 
  return 0; 
}


as per the tutorial the program should produce the output "Error: memory could not be allocated" if i give an input too big....but instead it's producing "Enter number:" for infinite times..... :(
i'm using "codeblocks 10.05" with "gcc". can anyone plz explain what's wrong?
Change this line.. it will fix it. The tutorial is wrong..

People tend to forget when they make a tutorial that not all compilers will give errors on certain ways of coding because they are using a compiler that is not as strict. So the proper way to write a tutorial is to find the strictest compiler you can find and then write a tutorial. MS VC ++ allows "sloppy" coding. Its just how it is. But MinGW or GCC in general do not.

NOTE : I quoted "sloppy" coding because although its not wrong, it is however not what all of the "other" compilers will agree on as for proper coding.

FROM this line :
if (p == 0)


TO this line
if (*p == 0)

I also use Code::Blocks 10.05. And I use MinGW as my compiler ( Its a GCC Compiler ).

In case you did not know this.. This line int * p; is assigning P to be a Pointer but it is telling the Pointer P that it is going to read an Integer. The P in itself is only a pointer, not an integer. How its assigning it to be a pointer is by the usage of the asterix * symbol.
Last edited on
@WinwordExonar
if(p == 0)
is testing if the pointer is null and if it is memory allocation failed. I see nothing wrong with the code , it should run fine but I cannot test in code::blocks.
Right, but you need the * in front of it to know that its a pointer on some compilers. if(*p == 0) P in itself on that line thinks its an integer until you add the * in front of it so that some compilers will know what it is.

Compilers like GCC and others like it cannot see it that way. They do not know how to interpret the if(p == 0) any other way then it thinking p is an integer. Again, its about the compilers. VC++ allows this, others do not.
Last edited on
Adding the asterisk dereferences the pointer to access its value. Here he needs to check if the pointer is null to test if allocation succeeded. Try his code in ideone.com, I just tested and it works fine.
hey WinwordExonar thanks for the solution.....
anyway, i was trying to use the compilers in "cygwin" and was able to do it just a few minutes before.....but using "cygwin" i got the exact same result as the tutorial claimed........ :(
rather changing from :
if (p == 0)
to this :
if (*p == 0)
gave me these errors :
How many numbers would you like to type? 10000000000000
      1 [main] 06 - DynamicMemory 4936 exception::handle: Exception: STATUS_ACCESS_VIOLATION
    544 [main] 06 - DynamicMemory 4936 open_stackdumpfile: Dumping stack trace to 06 - DynamicMemory.exe.stackdump

Process returned 35584 (0x8B00)   execution time : 3.958 s
Press any key to continue.


then i checked the code again in coldeblocks but now with the built-in MinGW gcc compiler and ur corrections worked perfect!!! :|
(i.e. writing if (*p == 0) instead of if (p == 0)
output:
How many numbers would you like to type? 1000000000000000
Error: memory could not be allocated
Process returned 0 (0x0)   execution time : 1.746 s
Press any key to continue.
)


i wonder why this happened.....i thought both cygwin & MinGW use gcc as compiler....why the output differs?
Last edited on
naraku, how would you be able to know if that site is not using the VC++ compiler in general. Or that they are using MS compilers ? The difference is that the code works fine with the * there too so that ALL compilers can read it.

Glad I was able to help kOdL3R. People tend to forget that not everyone uses the MS version of the C++ compilers.

Cygwin and MinGW have a slightly different way of compiling BASED OFF OF the GCC compiler.
Last edited on
In ideone on left hover over c++ it shows gcc-4.3.4. Yes, if(p* == 0) will work because it is a valid statement, but it is testing if p[0] == 0, not if the memory location pointed to by p is 0 aka null.
Naraku, try inputting a number larger then 130000. I have 8 gigs ram on my computer. I type in 131000 and I get the allocation error do to not enough memory to allocate. I type in 130000 and it allocates my memory. When I take the Astrex away, it doesn't work. It would allow me to use ANY number I want, as large as I want. In other words, without that * symbol, this program is useless on some compilers.
Last edited on
If this fails cin >> i; you don't know what value i will hold. It might hold a value that is small enough to not cause a crash but big enough so that it looks like the for loop runs forever.

Add a check to test if i was read without error.

This is correct if (p == 0) and should not depend on compiler

yes, without the *, the code allows to use any big numbers u want to in MinGW gcc in coldeblocks as WinwordExonar said.
however, what's the difference between these checks :
if (p == 0)
and
if (*p == 0)
Last edited on
The asterisk in that statement has nothing to do with whether allocation succeeds or not. You are testing if p[0] == 0 which should always fail as you have not initialized anything in the array at that point.
Last edited on
if (p == 0) checks if p is null pointer
if (*p == 0) is the same as if (p[0] == 0) and is not allowed if p is a null pointer so the program might crash, behave strange or just "work".
Last edited on
Peter, your comparing if its an integer. We are not talking about the integer here. We are talking about if it can see where the pointer is going to be at once the input has been given. It will error out if the pointer finds out that the address number you typed in doesn't exist. So it returns a NULL or 0. If you input a number of where it can be seen, then the pointer, which is assigned to find an integer, can READ the integer input from that pointer location.

the *p in this case means P is the actual pointer. Without the * in front of the p it becomes an integer and that's the problem here. It allows any number as if it was an integer JUST as you describe. It then doesn't work as the tutorial was specified to work as.

UPDATE : Your trying to compare P[0] to a pointer. Its not the same thing. if (p[0] == 0) means your assigning it to be an array. We are not talking about an Array here.

if (*p == 0) is not the same as if (p[0] == 0).
Last edited on
WinwordExonar wrote:
We are not talking about an Array here. if (*p == 0) is not the same as if (p[0] == 0).

Yes we are, and yes it is.
Last edited on
WinwordExonar, no, p is a pointer so doing if (p == 0), if (p == NULL), if (!p) all check if p is a null pointer. If you try to dereference a null pointer *p you have undefined behaviour (UB) and in this case the standard gives no guarantees what happens what so ever. Compilers might give additional guarantees but don't rely on it. The behaviour is likely to change just by passing different compiler flags.
Last edited on
Peter, please explain why it works on MS VC++ only then and not on any other compilers we have tried ? Its why this thread is posted in the first place. Maybe there is something missing in that tutorial that we are not seeing.

The * for us works fine.. but without it, it never works. So please explain.
I've tested on ideone.com which uses gcc-4.3.4 so I don't believe it is a compiler issue.
WinwordExonar, It's UB as I said. If your program is incorrect don't expect anything. I mentioned earlier you should check if cin >> i; fails before calling new.
Last edited on
I ask the question again Naraku, where are you seeing where it says "which" compiler your using ? On the left hand side it just gives the menu of what language. Doesn't say anything about which compiler. So if I am missing this please explain.
Pages: 1234