This question already has answers here:
Dynamically allocating an array of objects
(7 answers)
Closed 8 years ago.
Im learning at the moment c++ with a book.
I have many problems with the pointers...
int i;
cin >> i;
const int *quantity = &i;
int array[*quantity];
Is that correct? Can i control now the size of the array during the programm is running?
That's very nearly correct, except that the size of the array (which you've attempted to allocate on the stack here) has to be known at compile time, so no you can't do this.
However, you can allocate an array at runtime using new[], which will let you pass in a size that's not a compile time constant (new allocates on the heap):
int* array = new int[*quantity];
// ...
delete[] array; // Manual allocations with `new` require manual deallocations
Note that in your particular code example, there's no need to play with pointers at all -- you can just use i directly:
int* array = new int[i];
No, this is incorrect. Array size must be a constant expression, which means that it can be evaluated during compilation, and this is not the case for your code.
If you want arrays of different sizes, you can use dynamic allocation:
int* array = new int[i];
Or much better use std::vector:
std::vector<int> array(i);
Arrays are a fixed size in memory. Because arrays also represent a contiguous block of objects in memory, by definition the same array cannot change size in memory, because it would then need to move memory that may not even belong to the same application.
There are ways to move your array, however, copying it to a new array with more space when it gets full, and there are more mutable types such as std::Vector, but an array as deifned here cannot ever change size.
What this code would instead do is
place a value in i
Place a value in quantity representing the address (pointer) of i
Create a new array using the value in the address quantity
Note that pointers are addresses, specifically saying the byte address in RAM of a given variable (try printing a pointer directly, for example!). The * and & operators quickly say "get value at address" and "get address of"
Related
I know that arrays can be created on the stack with syntax such as int array[5]; where the size must be known at compile time and array is a non modifiable l-value.
You can also create an array dynamically on the heap with new such as int* array = new int[5]; where it becomes possible to have a size of variable length and resize the array.
But what about something like:
int* array;
array[2] = 3;
cout << array[2] << endl;
Which creates an array on the stack that appears to be resizable because I can continue adding elements. The only other thing that should be kept track of is the size.
I wrote the above code accidentally in a project and I haven't seen it used ever. I not sure if it should be used at all, but I'm also not sure what's incorrect about it.
But what about something like:
int* array;
array[2] = 3;
cout << array[2] << endl;
Which creates an array on the stack that appears to be resizable because I can continue adding elements. The only other thing that should be kept track of is the size.
Nope. Unfortunately, C++ doesn't work like that. You need to allocate the array with new if you want to create a dynamic array with raw pointers.
This is because pointers only hold addresses. They don't actually guarantee that there is memory allocated at that address. Thus, you will need to allocate memory at an address if you want to use it.
If you want a dynamically allocated memory, you have other options including using std::vector, or std::unique_ptr, or std::shared_ptr. You can find more information on this and some examples at this question.
Writing int *array; does not create an array, it declares a pointer to some random memory page, and if you try to dereference this pointer, your program will receive “Segmentation fault” signal and will be shut down. Never use pointers without their proper initialization using addresses of existing objects, or allocated objects (using new), or functions/methods which return valid address.
I am confused about how to create a dynamic defined array:
int *array = new int[n];
I have no idea what this is doing. I can tell it's creating a pointer named array that's pointing to a new object/array int? Would someone care to explain?
new allocates an amount of memory needed to store the object/array that you request. In this case n numbers of int.
The pointer will then store the address to this block of memory.
But be careful, this allocated block of memory will not be freed until you tell it so by writing
delete [] array;
int *array = new int[n];
It declares a pointer to a dynamic array of type int and size n.
A little more detailed answer: new allocates memory of size equal to sizeof(int) * n bytes and return the memory which is stored by the variable array. Also, since the memory is dynamically allocated using new, you should deallocate it manually by writing (when you don't need anymore, of course):
delete []array;
Otherwise, your program will leak memory of at least sizeof(int) * n bytes (possibly more, depending on the allocation strategy used by the implementation).
The statement basically does the following:
Creates a integer array of 'n' elements
Allocates the memory in HEAP memory of the process as you are using new operator to create the pointer
Returns a valid address (if the memory allocation for the required size if available at the point of execution of this statement)
It allocates space on the heap equal to an integer array of size N,
and returns a pointer to it, which is assigned to int* type pointer called "array"
It allocates that much space according to the value of n and pointer will point to the array i.e the 1st element of array
int *array = new int[n];
The new operator is allocating space for a block of n integers and assigning the memory address of that block to the int* variable array.
The general form of new as it applies to one-dimensional arrays appears as follows:
array_var = new Type[desired_size];
In C/C++, pointers and arrays are (almost) equivalent.
int *a; a[0]; will return *a, and a[1]; will return *(a + 1)
But array can't change the pointer it points to while pointer can.
new int[n] will allocate some spaces for the "array"
As of C++11, the memory-safe way to do this (still using a similar construction) is with std::unique_ptr:
std::unique_ptr<int[]> array(new int[n]);
This creates a smart pointer to a memory block large enough for n integers that automatically deletes itself when it goes out of scope. This automatic clean-up is important because it avoids the scenario where your code quits early and never reaches your delete [] array; statement.
Another (probably preferred) option would be to use std::vector if you need an array capable of dynamic resizing. This is good when you need an unknown amount of space, but it has some disadvantages (non-constant time to add/delete an element). You could create an array and add elements to it with something like:
std::vector<int> array;
array.push_back(1); // adds 1 to end of array
array.push_back(2); // adds 2 to end of array
// array now contains elements [1, 2]
I have a program that I've written that requires me to declare an array as such
float (*array)[3] = new float[faces * 3][3];
Now I understand the syntax and all, this is an array of pointers to fixed size arrays. What I don't understand is the underlying organization behind this. Since there was only one memory allocation (for the array of pointers) how does the memory for the fixed size arrays get allocated?
Along the same thread, since there was only one allocation there should be one deletion, meaning the array is deleted by
delete[] array;
but I'm confused as to how this gets all of the memory, given that it seems only the array of pointers has been deleted, as opposed to the memory they pointed to.
This is not an array of pointers to fixed size arrays. This is a pointer to a multidimensional array. Multidimensional arrays are implemented as one dimensional array, with some calculation upon accessing elements.
The memory layout is exactly like in this statement:
float *array = new float[(faces * 3) * 3];
or in this one (except faces must be constant expression, and the allocation is now on the stack):
float arr3[faces*3][3];
float (*array)[3] = &arr3; // note the "&". it is not a decaying here
and this is a more familiar form of this pointer:
void something(float array[][3]); // this is not an array, but a pointer to one.
Note that the arrays of different sizes/dimensions are distinct types, and if you want to access a one dimensional array as a multi-dimensinal one, now will need to do the calculation of array[3][2] yourself.
Baby steps.
First, these fixed-length arrays of float[3] seem like special types. I'm guessing you'll be doing specific operations with them. You should wrap a float[3] with the functions and operations that will work with them into a class. You may decide to use Vector<float> internally and keep them at size 3, but std::vector was designed to be appended to and removed from. I think there is another "std template" class that was designed for fixed-length multiples, but I don't know which. I don't use the STL much.
Once you've objectified your float[3]'s, however you do it, I think the rest will become easier as you start to see more clearly.
I have been working on sorting algorithms for school and have come across a strange issue. When ever I create an integer array bigger than six elements large I get breaks in "free.c" and heap corruption errors.
The code I have narrowed it down to is as follows.
#include <iostream>
using namespace std;
int main(){
int * pie = new int(7);
pie[6] = 1;
cout << pie[6];
return 0;
}
Sometimes you need to assign more than just the last value, however I can get this error on Visual Studio 2012 and 2010 on multiple computers, in Linux this code works perfectly fine however.
Is this an issue with Windows, have I been doing dynamic int arrays wrong forever or what?
Note:After running this several times, sometimes the output in VS will say something about adding a heap protection shunt which seems to resolve the test throwing the exception but still doesn't solve the issue in larger applications (and I would feel bad having to need such protection applied to my code).
Thanks!
In this case you are allocating a single integer which has the value 7 but treating it like an array of 7 elements. You need to do an actual array allocation
int* pie = new int[7];
Also wouldn't hurt to free the memory at the end of main :)
delete[] pie;
new int(7) allocates a single int, value 7. It doesn't allocate space for 7 int values.
To solve your issue, you need to use:
int* pie = new int[7];
Otherwise, you only allocate one int.
Executing the code below, will overwrite whatever is beyond the array boundaries.
int * pie = new int(7);
pie[6] = 1;
This can lead to hard-to-track random bugs. For instance if it overwrites a pointer…
More informations in: C++ Dynamic Memory allocations
Operators new and new[]
In order to request dynamic memory we use the operator new. new is followed by a data type specifier and -if a
sequence of more than one element is required- the number of these
within brackets []. It returns a pointer to the beginning of the new
block of memory allocated. Its form is:
pointer = new type pointer = new type [number_of_elements]
The first expression is used to allocate memory to contain one single element of type type. The second one is used to assign a
block (an array) of elements of type type, where number_of_elements
is an integer value representing the amount of these. For example:
int * bobby;
bobby = new int [5];
In this case, the system dynamically assigns space for five elements
of type int and returns a pointer to the first element of the
sequence, which is assigned to bobby. Therefore, now, bobby points to
a valid block of memory with space for five elements of type int.
Operators delete and delete[]
Since the necessity of dynamic memory is usually limited to specific
moments within a program, once it is no longer needed it should be
freed so that the memory becomes available again for other requests of
dynamic memory. This is the purpose of the operator delete, whose
format is:
delete pointer;
delete [] pointer;
The first expression should be used to delete memory allocated for a
single element, and the second one for memory allocated for arrays of
elements.
The value passed as argument to delete must be either a pointer to a
memory block previously allocated with new, or a null pointer (in the
case of a null pointer, delete produces no effect).
I'm familiar with Java and trying to teach myself C/C++. I'm stealing some curriculum from a class that is hosting their materials here. I unfortunately can't ask the teacher since I'm not in the class. My concern is with the section under "dynamically declared arrays":
If you
want to be able to alter the size of
your array at run time, then declare
dynamic arrays. These are done with
pointers and the new operator. For the
basics on pointers, read the pointers
section.
Allocate memory using new, and then
you access the array in the same way
you would a static array. For example,
int* arrayPtr = new int[10]; for
(int i = 0; i < 10; i++) {
arrayPtr[i] = i; }
The memory picture is identical to the
static array, but you can change the
size if you need to. Don't forget you
must deallocate the memory before
allocating new memory (or you will
have a memory leak).
delete [] arrayPtr; // the []
is needed when deleting array pointers
arrayPtr = new int[50]; . . .
When you're completely done with the
array, you must delete its memory:
delete [] arrayPtr;
Dynamic multi-dimensional arrays are
done in a similar manner to Java. You
will have pointers to pointers. For an
example, see a
My understanding is that an array in C is simply a reference to the memory address of the first element in the array.
So, what is the difference between int *pointerArray = new int[10]; and int array[10]; if any?
I've done some tests that seem to indicate that they do the exact same thing. Is the website wrong or did I read that wrong?
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
// Initialize the pointer array
int *pointerArray = new int[10];
for (int i = 0; i < 10; i++){
pointerArray[i] = i;
}
// Initialize the regular array
int array[10];
for (int i = 0; i < 10; i++){
array[i]= i;
}
cout << *(pointerArray + 5) << endl;
cout << *(array + 5) << endl;
cout << pointerArray[5] << endl;
cout << array[5] << endl;
cout << pointerArray << endl;
cout << array << endl;
return 0;
}
Output:
5
5
5
5
0x8f94030
0xbfa6a37c
I've tried to "dynamically re-size" my pointer array as described on the site, but my new (bigger) pointer array ends up filled with 0's which is not very useful.
int array[10]; declares the array size statically, that means it is fixed - which is the only major difference. It also might be allocated to be inside the function's stack frame, i.e. on the program's stack. You do not need to worry about using delete [] on that kind of array, in fact, you might crash the program if you delete it.
When you use operator new, you allocate memory dynamically which could be slower and the memory usually comes from the heap rather than the program's stack (though not always). This is better in most cases, as you are more limited in the stack space than the heap space. However, you must watch out for memory leaks and delete[] your stuff when you don't need it anymore.
As to your array being filled with zeros, what your class material does not say is that you have to do this:
int *arr = new int[20]; // old array
//do magic here and decide that we need a bigger array
int *bigger = new int[50]; // allocate a bigger array
for (int i = 0; i < 20; i++) bigger[i] = arr[i]; // copy the elements from the old array into the new array
delete[] arr;
arr = bigger;
That code extends the array arr by 30 more elements. Note that you must copy the old data into the new array, or else it will not be there (in your case, everything becomes 0).
My understanding is that an array in C is simply a reference to the memory address of the first element in the array.
So, what is the difference between int *pointerArray = new int[10]; and int array[10]; if any?
What you mention is the reason for much confusion in any C/C++ beginner.
In C/C++, an array corresponds to a block of memory sufficiently large to hold all of its elements. This is associated to the [] syntax, like in your example:
int array[10];
One feature of C/C++ is that you can refer to an array by using a pointer to its type. For this reason, you are allowed to write:
int* array_pointer = array;
which is the same as:
int* array_pointer = &array[0];
and this allows to access array elements in the usual way: array_pointer[3],
but you cannot treat array as a pointer, like doing pointer arithmetics on it (i.e., array++ miserably fails).
That said, it is also true that you can manage arrays without using the [] syntax at all and just allocate arrays by using malloc and then using them with raw pointers. This makes the "beauty" of C/C++.
Resuming: a distinction must be made between the pointer and the memory that it points to (the actual array):
the [] syntax in declarations (i.e., int array[10];) refers to both aspects at once (it gives you, as to say, a pointer and an array);
when declaring a pointer variable (i.e., int* p;), you just get the pointer;
when evaluating an expression (i.e., int i = p[4];, or array[4];), the [] just means dereferencing a pointer.
Apart from this, the only difference between int *pointerArray = new int[10]; and int array[10]; is that former is allocated dynamically, the latter on the stack.
Dynamically allocated:
int * pointerArray = new int[10];
[BTW, this is a pointer to an array of 10 ints, NOT a pointer array]
Statically allocated (possibly on the stack):
int array[10];
Otherwise they are the same.
The problem with understanding C/C++ arrays when coming from Java is that C/C++ distinguishes between the array variable and the memory used to store the array contents. Both concepts are important and distinct. In Java, you really just have a reference to an object that is an array.
You also need to understand that C/C++ has two ways of allocating memory. Memory can be allocated on the help or the stack. Java doesn't have this distinction.
In C and C++, an array variable is a pointer to the first element of the array. An array variable can exist on the heap or the stack, and so can the memory that contains its contents. And they can be difference. Your examples are int arrays, so you can consider the array variable to be an int*.
There are two differences between int *pointerArray = new int[10]; and int array[10];:
The first difference is that the memory that contains the contents of the first array is allocated on the heap. The second array is more tricky. If array is a local variable in a function then its contents are allocated on the stack, but if it is a member variable of a class then its contents are allocated wherever the containing object is allocated (heap or stack).
The second difference is that, as you've realised, the first array is dynamic: its size can be determined at run-time. The second array is fixed: the compiler must be able to determine its size at compile time.
First, I'd look for some other place to learn C++. The page you cite is
very confusing, and has little to do with the way one actually programs
in C++. In C++, most of the time, you'd use std::vector for an array,
not the complex solutions proposed on the page you cite. In practice,
you never use operator new[] (an array new).
In fact, std::vector is in some ways more like ArrayList than simple
arrays in Java; unlike an array in Java, you can simply grow the vector
by inserting elements into it, preferrably at the end. And it supports
iterators, although C++ iterators are considerably different than Java
iterators. On the other hand, you can access it using the []
operator, like a normal array.
The arrays described on the page you cite are usually called C style
arrays. In C++, their use is mostly limited to objects with static
lifetime, although they do occasionally appear in classes. In any case, they are never allocated dynamically.
The main difference is that some operations that are allowed on pointers are not allowed on arrays.
On the one hand:
int ar[10];
is using memory allocated on the stack. You can think of it also locally available and while it is possible to pass a pointer / reference to otehr functions, the memory will be freed as soon as it goes out of scope (in your example at the end of the main method but that's usually not the case).
On the other hand:
int ar* = new int[10];
allocates the memory for the array on the heap. It is available until your whole program exits or it is deleted using
delete[] ar;
note, that for delete you need the "[]" if and only if the corresponding new has had them, too.
There is a difference but not in the area that you point to. *pointerArray will point to the beginning of a block of memory of size 10 bytes. So will array. The only difference will be where it is stored in memory. pointerArray is dynamically assigned memory (at run-time) and hence will go on the heap, while array[10] will be allocated at compile-time and will go to the stack.
It is true that you can get most of array functionality by using a pointer to its first element. But compiler knows that a static array is composed of several elements and the most notable difference is the result of the sizeof operator.
sizeof(pointerArray) = sizeof int*
sizeof(array) = 10 * sizeof int