17

In many tutorials, the first code samples about dynamic memory start along the lines of:

int * pointer;
pointer = new int;        // version 1
//OR
pointer = new int [20];    // version 2

They always proceed to explain how the second version works, but totally avoid talking about the first version.

What I want to know is, what does pointer = new int create? What can I do with it? What does it mean? Every tutorial without fail will avoid talking about the first version entirely. All I've found out (through messing about) is this:

#include <iostream>

using namespace std;

int main()
{
    int * pointer;
    pointer = new int;
   pointer[2] = 1932;   // pointer [2] exists? and i can  assign to it?!
   cout << pointer[2] << endl;      // ... and access it successfully?!
};

The fact that I can subscript pointer tells me so far that pointer = new int implicitly creates an array. But if so, then what size is it?

If someone could help clear this all up for me, I'd be grateful...

Douglas
  • 1,134
  • 9
  • 25
code shogan
  • 799
  • 1
  • 8
  • 23
  • 2
    Also note that memory allocated with **new** must be freed with **delete**, while memory allocated with **new []** must be freed with **delete []**, or disaster may occur. They are two different operators. This is one of the dumbest things ever invented in any programming language, and that is no small feat to achieve. – Lundin May 18 '11 at 11:23
  • It could be your compiler that is helping you a bit by allocating buffers on both sides of what you want. You can read about it here - [_malloc_dbg (CRT)](http://msdn.microsoft.com/en-us/library/faz3a37z(VS.80).aspx) – Default May 18 '11 at 11:29
  • I also found this to be useful with c++ and memory in general: [Memory Allocation](http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html) – code shogan May 18 '11 at 12:51
  • Curious that a tutorial would talk about `new int[n]`, and not simply `new int`. In well over 20 years of C++ programming, I don't think I've ever used an array `new`. – James Kanze May 18 '11 at 17:40
  • @James I find that intresting... oh and the site is [cplusplus](http://www.cplusplus.com/doc/tutorial/dynamic/) – code shogan May 18 '11 at 18:12

10 Answers10

14

This is a typical error in C and C++ for beginners. The first sentence, creates a space for holding just an int. The second one creates a space for holding 20 of those ints. In both cases, however, it assigns the address of the beginning of the dynamically-reserved area to the pointer variable.

To add to the confusion, you can access pointers with indices (as you put pointer[2]) even when the memory they're pointing is not valid. In the case of:

int* pointer = new int;

you can access pointer[2], but you'd have an undefined behavior. Note that you have to check that these accesses don't actually occur, and the compiler can do usually little in preventing this type of errors.

Diego Sevilla
  • 27,060
  • 3
  • 52
  • 82
14

My teacher explained it like this.
Think of cinema. The actual seats are memory allocations and the ticket you get are the pointers.

int * pointer = new int;

This would be a cinema with one seat, and pointer would be the ticket to that seat

pointer = new int [20] 

This would be a cinema with 20 seats and pointer would be the ticket to the first seat. pointer[1] would be the ticket to the second seat and pointer[19] would be the ticket to the last seat.

When you do int* pointer = new int; and then access pointer[2] you're letting someone sit in the aisle, meaning undefined behaviour

Default
  • 10,565
  • 8
  • 60
  • 99
  • 4
    I've never heard that analogy. I like it, specifically how "sitting inthe aisles" is undefined behavior. – Robᵩ May 18 '11 at 14:15
10

This creates only one integer.

pointer = new int;        // version 1

This creates 20 integers.

pointer = new int [20]    // version 2

The below is invalid, since pointer[2] translates as *(pointer + 2) ; which is not been created/allocated.

int main()
{
    int * pointer;
    pointer = new int;
   pointer[2] = 1932;   // pointer [2] exists? and i can  assign to it?!
   cout << pointer[2] << endl;      // ... and access it succesfuly?!
};

Cheers!

Ricko M
  • 1,584
  • 4
  • 21
  • 41
2

new int[20] allocates memory for an integer array of size 20, and returns a pointer to it.

new int simply allocates memory for one integer, and returns a pointer to it. Implicitly, that is the same as new int[1].

You can dereference (i.e. use *p) on both pointers, but you should only use p[i] on the pointer returned by the new int[20].

p[0] will still work on both, but you might mess up and put a wrong index by accident.

Update: Another difference is that you must use delete[] for the array, and delete for the integer.

evgeny
  • 2,474
  • 14
  • 27
1

pointer = new int allocates enough memory on the heap to store one int.

pointer = new int [20] allocates memory to store 20 ints.

Both calls return a pointer to the newly allocated memory.

Note: Do not rely on the allocated memory being initialized, it may contain random values.

Tony the Pony
  • 37,471
  • 63
  • 170
  • 273
1

pointer = new int; allocates an integer and stores it's address in pointer. pointer[2] is a synonym for pointer + 2. To understand it, read about pointer arithmetic. This line is actually undefined behavior, because you are accessing memory that you did not previously allocate, and it works because you got lucky.

Björn Pollex
  • 70,106
  • 28
  • 177
  • 265
1

int* p = new int allocates memory for one integer. It does not implictly create an array. The way you are accessing the pointer using p[2] will cause the undefined behavior as you are writing to an invalid memory location. You can create an array only if you use new[] syntax. In such a case you need to release the memory using delete[]. If you have allocated memory using new then it means you are creating a single object and you need to release the memory using delete.

Naveen
  • 69,046
  • 43
  • 164
  • 225
1

*"The fact that i can subscript pointer tells me so far that I pointer = new int implicitly creates an array. but if so, then what size is it?" *

This was the part of the question which I liked the most and which you emphasize upon.

As we all know dynamic memory allocation makes use of the space on the Stack which is specific to the given program. When we take a closer look onto the definition of new operator :-

void* operator new[] (std::size_t size) throw (std::bad_alloc);

This actually represents an array of objects of that particular size and if this is successful, then it automatically Constructs each of the Objects in the array. Thus we are free to use the objects within the bound of the size because it has already been initialized/constructed.

int * pointer = new int;

On the other hand for the above example there's every possibility of an undefined behaviour when any of

*(pointer + k) or *(k + pointer)

are used. Though the particular memory location can be accessed with the use of pointers, there's no guarantee because the particular Object for the same was not created nor constructed.This can be thought of as a space which was not allocated on the Stack for the particular program.

Hope this helps.

NirmalGeo
  • 763
  • 4
  • 11
0

It does not create array. It creates a single integer and returns the pointer to that integer. When you write pointer[2] you refer to a memory which you have not allocated. You need to be carefull and not to do this. That memory can be edited from the external program which you, I belive, don't want.

Narek
  • 35,407
  • 69
  • 202
  • 359
0
int * pointer; pointer = new int;  // version 1
//OR 
pointer = new int [20]             // version 2 

what I want to know is, what does pointer = new int create? what can I do with it? what does it mean? Every tutorial without fail will avoid talking about the first version entirely

The reason the tutorial doesn't rell you what to do with it is that it really is totally useless! It allocates a single int and gives you a pointer to that.

The problem is that if you want an int, why don't you just declare one?

int i;
Bo Persson
  • 86,087
  • 31
  • 138
  • 198
  • according to the link I posted below my question it actually does have a purpose. If i did `int i` then memory for i would be reserved as soon as the program enters runtime and would continue to be reserved untill it exits. The problem is when you only want to store something for a while, especially if you program is huge and the excecution paths vary greatly. then `new int i` comes into play. Now I wouldn't need this on a day to day, but I wanted to understand it and know how to use it if ever need be. – code shogan May 18 '11 at 17:40
  • @code shogan - The problem with the example is that the pointer to the `int` takes at least as much space as the `int` itself. That makes it a net loss. If you need your integer only sometimes, you can declare it inside a function. Then it will live just as long as the function is active. – Bo Persson May 18 '11 at 17:50
  • ...and I wount have to `delete pointer`. Okay I give in `new int;` is a little useless.:) – code shogan May 18 '11 at 18:17