I know it's a dumb question but I hope someone can help me here:
int size = 5;
int* newarray = new int[size];
This Array won't work. It will have
newarray[1] = very big minus number;
And not an array of Size 5. What am I doing wrong?
It would not be a dump question if it would not be for vague 'won't work' statement. You should be very specific when you describe the problem.
In your particular case, the array 'works'. But the individual elements of the array are not initialized with this statement. This is by design. If you want them to be initialized to 0, you can use
int* newarray = new int[size]();
If you want it initialized to anything else, you will have to write code to initialize every member to desired value.
In C++, when you dynamically initialize an array using new keyword like:
1. int *array = new int[size]
2. int *array = new int[size]()
(1) allocates a portion of memory for that particular type and size in the memory, followed by default initialization (may or may not be zero). While (2) will initialize everything to 0.
However since memory allocation is contagious, you can still access elements outside provided size but will have some garbage value. It's certainly not recommended to go outside of allocated size, since it may lead to unexpected behavior.
So whenever you see a negative value, you are probably going out of the scope of allocated area.
Related
Possible Duplicate:
is this a variable or function
I mistakenly used something like:
int *arr = new int(100);
and it passes compile, but I knew this is wrong. It should be
int *arr = new int[100];
What does the compiler think it is when I wrote the wrong one?
The first line allocates a single int and initializes it to 100. Think of the int(100) as a constructor call.
Since this is a scalar allocation, trying to access arr[1] or to free the memory using delete[] would lead to undefined behaviour.
Wikipedia new(C++) quote:
int *p_scalar = new int(5); //allocates an integer, set to 5. (same syntax as constructors)
int *p_array = new int[5]; //allocates an array of 5 adjacent integers. (undefined values)
UPDATE
In the current Wikipedia article new and delete (C++) the example is removed.
Additionally here's the less intuitive but fully reliable C++ reference for new and new[].
It allocates one object of type int and initialized it to value 100.
A lot of people doesn't know that you can pass an initializer to new, there's a particular idiom that should be made more widely known so as to avoid using memset:
new int[100]();
This will allocate an array of int and zero-initialize its elements.
Also, you shouldn't be using an array version of new. Ever. There's std::vector for that purpose.
The first one creates a single new integer, initializes it to the value 100 and returns a pointer to it.
In C/C++ there is no difference between a pointer to an array and a pointer to a single value (a pointer to an array is in fact just a pointer to its first element). So this is a valid way to create an array with one element.
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"
Here is a code snippet I was working with:
int *a;
int p = 10;
*(a+0) = 10;
*(a+1) = 11;
printf("%d\n", a[0]);
printf("%d\n", a[1]);
Now, I expect it to print
10
11
However, a window appears that says program.exe has stopped working.
The if I comment out the second line of code int p = 10; and then tun the code again it works.
Why is this happening? (What I wanted to do was create an array of dynamic size.)
There are probably at least 50 duplicates of this, but finding them may be non-trivial.
Anyway, you're defining a pointer, but no memory for it to point at. You're writing to whatever random address the pointer happened to contain at startup, producing undefined behavior.
Also, your code won't compile, because int *a, int p = 10; isn't syntactically correct -- the comma needs to become a semicolon (or you can get rid of the second int, but I wouldn't really recommend that).
In C, you probably want to use an array instead of a pointer, unless you need to allocate the space dynamically (oops, rereading, you apparently do want to -- so you need to use malloc to allocate the space, like a = malloc(2); -- but you also want to check the return value to before you use it -- at least in theory, malloc can return a null pointer). In C++, you probably want to use a std::vector instead of an array or pointer (it'll manage dynamic allocation for you).
No memory is being allocated for a, it's just an uninitialized pointer to an int (so there are two problems).
Therefore when data is stored in that location, the behavior is undefined. That means you may sometimes not even get a segmentation fault/program crash, or you may -> undefined. (Since C doesn't do any bounds checking, it won't alert you to these sort of problems. Unfortunately, one of the strength of C is also one of its major weaknesses, it will happily do what you ask of it)
You're not even allocating memory so you're accessing invalid memory...
Use malloc to allocate enough memory for your array:
int* a = (int*) malloc(sizeof(int)*arraySize);
//Now you can change the contents of the array
You will need to use malloc to assign memory that array.
If you want the size to by dynamic you will need to use realloc every time you wish to increase the size of the array without destroying the data that is already there
You have to allocate storage for the array. Use malloc if you're in C, new if it's C++, or use a C++ std::vector<int> if you really need the array size to be dynamic.
First a has not been initialized. What does it point to? Nothing, hopefully zero, but you do not know.
Then you are adding 1 to it and accessing that byte. IF a were 0, a+1 would be 1. What is in memory location 1?
Also you are bumping the address by one addressable memory unit. This may or may not be the size of an integer on that machine.
Related to a recent question, I wrote the following code:
int main()
{
char* x = new char[33];
int* sz = (int*)x;
sz--;
sz--;
sz--;
sz--;
int szn = *sz; //szn is 33 :)
}
I do know it's not safe and would never use it, but it brings to mind a question:
Is the following safe? Is it a memory leak?
char* allocate()
{
return new char[20];
}
int main()
{
char* x = allocate();
delete[] x;
}
If it's safe, doesn't that mean we can actually find the size of the array? Granted, not in a standard way, but is the compiler required to store information about the size of the array?
I am not using or plan on using this code. I know it is undefined behavior. I know it isn't guaranteed by anything. It's just a theoretical question!
Is the following safe?
Yes, of course that's safe. First snippet has UB however.
If it's safe, doesn't that mean we can actually find the size of the array? Granted, not in a standard way, but is the compiler required to store information about the size of the array?
Yes, generally extra data is stored before the first element. This is used to call the correct number of destructors. It's UB to access this.
required to store information about the size of the array?
No. It only requires delete[] work as expected. new int[10] could simply be a plain malloc call, which would not necessarily store the requested size 10.
This is safe, and is not a memory leak. The standards require that delete[] handle the freeing of memory by any array allocation.
If it's safe, doesn't that mean we can actually find the size of the array?
The standards don't put specific requirements on where and how the allocated size is stored. This could be discoverable as shown above, but different compilers/platforms could also use a completely different methodology. As such, it's not safe to rely on this technique to discover the size.
I know that in c, the size of any malloc on the heap resides before the pointer. The code for free relies on this. This is documented in K&R.
But you should not rely on this always being there or always being in the same position.
If you want to know the array length then I would suggest you create a class or struct to record capcity along side the actual array, and pass that around your program where you would previously just pass a char*.
int main()
{
char* x = new char[33];
int* sz = (int*)x;
sz--;
sz--;
sz--;
sz--;
int szn = *sz; //szn is 33 :)
}
This is an undefined behavior, because you access the memory location that you didn't allocate.
is the compiler required to store information about the size of the array?
No.
If it's safe, doesn't that mean we can actually find the size of the array?
You do not do anything special in the 2nd code snipet, therefore it's safe. But there are no ways to get the size of the array.
I am not sure it the delete must know the size of the array when the array is allocated with basic types (that doesn't demand a call to the destructor). In visual studio compilers, the value is stored only for user defined objects (in this case, delete[] must know the size of the array, as it must call their destructors).
Where in the memory the size is allocated is undefined (in visual studio it is in the same place of the gcc).
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.14
There are two ways to destroy an array, depending on how it was created. In both cases the compiler is required to call a destructor for each element of the array, so the number of elements in the array must be known.
If the array is an automatic variable on the stack, the number of elements is known at compile time. The compiler can hard-code the number of elements in the code it emits for destroying the array.
If the array is dynamically allocated on the heap, there must be another mechanism for knowing the element count. That mechanism is not specified by the standard, nor is it exposed in any other fashion. I think that putting the count at an offset from the front of the array is a common implementation, but it's certainly not the only way, and the actual offset is just a private implementation detail.
Since the compiler must know how many elements are in the array, you'd think it would be possible for the standard to mandate a way of making that count available to programs. Unfortunately this is not possible because the count is only known at destruction time. Imagine that the standard included a function count_of that could access that hidden information:
MyClass array1[33];
MyClass * array2 = new MyClass[33];
cout << count_of(array1) << count_of(array2); // outputs 33 33
Foo(array1);
Foo(array2);
MyClass * not_array = new MyClass;
Foo(not_array);
void Foo(MyClass * ptr)
{
for (int i = 0; i < count_of(ptr); ++i) // how can count_of work here?
...
}
Since the pointer passed to Foo has lost all its context, there's no consistent way for the compiler to know how many elements are in the array, or even if it's an array at all.
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