Reputation: 314
I'm learning the basics of C++ with previous experience in Java based upon the official tutorial at "http://www.cplusplus.com/doc/tutorial/dynamic/". The tutorial presents the operator "new" as a way to define a array's size at runtime; however, this feels like a useless addition, since I can easily just define an array's size with a variable by doing
int numbers [size];
in contrast to
int * numbers = new int [size];
By testing on my own I already realized that using the new operator allows for going over the pre-allocated memory size (I could write to numbers[7] when I initialized it with size = 5), whereas the first line of code does not. I have three basic questions about this operator:
Upvotes: 0
Views: 524
Reputation: 36597
int numbers [size];
in contrast to
int * numbers = new int [size];
The first, in standard C++, requires the value of size
to be known and fixed at compile time. The second allows the value of size
to be determined at run time (e.g. based on user input).
Some compilers allow the first form to be used with size
as a variable, but that is not standard C++. Such variable length arrays are a feature of C (from 1999) that some C++ compilers support as a non-standard extension. Other C++ compilers will diagnose an error (as required by the C++ standard).
How the first is allocated depends on context. For example;
arr
will have automatic storage duration and will cease to exist at the end of enclosing block (e.g. when the function returns).struct
or class
type, the array will be created whenever an instance of that struct
or class
is created.The first two above are, somewhat incorrectly, sometimes said to be created on "the stack". However, the C++ standard does not require that - "the stack" is an implementation detail associated with operating systems and runtime environment.
The second is said to allocate memory dynamically (using operator new
). The memory will exist until it is explicitly released (e.g. using the corresponding operator delete
).
Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with?
Yes. The behaviour is undefined by the C++ standard. Practically, it can seem to work correctly. It can also have unwanted effects, such as poisoning data used by your program or reformatting your hard drive. In nasty cases, it can seem to work correctly in your testing, only to have one of the unwanted effects when run by a paying client. Such occurrences tend to make for grumpy clients.
The behaviour is equally undefined whether working with a pointer or an array. Assigning a value to the tenth element of an array with five elements gives undefined behaviour, regardless of how the array is created (e.g. in either of your two options).
If it is dangerous to do so, what alternative could I use (if there is one) to setting up lists other than manually setting up (or using a library for) a linked list?
In C++, there are standard containers. Look up vector
(in the standard header <vector>
) for an example. Obviously it is possible to use a standard container incorrectly (and get unwanted effects) but it is easier to avoid problems using a standard container than it is with arrays or pointers.
Standard containers also handle memory allocation and deallocation automatically - there is no need for you, as the programmer, to manage dynamic memory directly (e.g. forgetting to release the memory when no longer needed).
Upvotes: 3
Reputation: 43078
What's the difference between the two lines of code above?
The difference is that the first one is not allowed in C++. Some compilers will allow it and may give a warning when special flags are supplied, whereas other compilers retch at the sight of it).
The second one is the way to go and pretty much does the same thing no matter what compiler you use.
Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with?
Yes it is. The behavior is undefined. If you don't get any exception at runtime, don't take that as a good thing because sooner than later, something will break surprisingly.
If it is dangerous to do so, what alternative could I use (if there is one) to setting up lists other than manually setting up (or using a library for) a linked list?
Are you asking for an alternative way to access memory that does not belong to you? The answer is DON'T DO IT!.
You can use one of C++'s containers as an alternative to creating a list of stuff. For a builtin linked list data structure, use std::list
or std::forward_list
. For random access containers, std::vector
is a great start, but if you know the size ahead of time (i.e. before runtime), then std::array
is the way to go.
Upvotes: 0
Reputation: 10998
What's the difference between the two lines of code above?
Assuming size
is a constant expression, the difference is the first example is allocated on stack while the second on heap and you need to remember to delete []
it.
Is it dangerous to write to a pointer address in memory in the array I didn't allocate to start with?
It's undefined behaviour to write outside bounds, but if you're within bounds you're ok:
constexpr int size = 5;
int arr[size];
arr[0] = 2;
If it is dangerous to do so, what alternative could I use
Use a std::vector
:
std::vector<int> arr;
Upvotes: 2