This is really a noob quick question.
Imagine you have a struct called "No" and the following piece of code:
No *v_nos; // What does this mean?
Where I took this from they were calling "v_nos" a array? Isn't it simply a pointer to a struct "No"?
Thanks.
Arrays and pointers are NOT the same. In your case, the variable is a pointer, not an array. Even if they are not the same, the confusion is quite common and you will find in many places (including C/C++ books) that they are the same thing. This means that you should get acquainted to people calling pointers arrays.
When the C language was developed they decided that instead of passing arrays by value (possibly requiring a huge amount of copying and stack memory) they would convert silently the array into a pointer to the first element and then pass that pointer to the function.
void f( int a[3] ); // valid and misleading
// what it means:
// void f( int *a);
void test() {
int array[3];
f( array );
// what it means:
// f( & array[0] )
}
For backwards compatibility C++ keeps that feature around and you cannot pass arrays by value, nor define a function that takes an array by value (in both cases it will be converted to a pointer to the first element silently). At the same time, you can use the array access syntax on pointers to simplify pointer arithmetic, making it more confusing:
int array[3];
int *pointer = array; // simplified:
// int * pointer = & array[0]
pointer[2]; // equivalent to *(pointer+2) or array[2]
This means that with regular functions both in C and C++ arrays silently decay into pointers and most people will have the idea that they are the same thing: an array is a pointer to the first element. Well, they are not.
Both in C and C++ they are different entities, even if some usage patterns are equivalent due to that design decision. But they are in fact different:
int array[3]; sizeof(array); // 3*sizeof(int)
int *p1=array; // sizeof(int*), usually 4/8 bytes for 32/64 bit
int *p2=new int[3]; // sizeof(int*)
After passing through a function/method call, they are all pointers:
void f( int array[3] ) { sizeof(array); } // sizeof(int*) it is really a pointer! size is ignored
void g( int *p ) { sizeof(array); } // sizeof(int*)
In C++ things become even more interesting, as pass-by-value is not the only available paradigm and you can pass by reference:
void f( int (&array)[3] ); // funny syntax to pass an array of 3 integers by reference
void testf() {
int array1[3]; f(array1); // correct
int array2[2]; // f(array2); compilation error, it is not an array of 3 ints!
int *p = array1; // f(p); compilation error, it is not an array of 3 ints!
}
void g( int array[3] ); // means: void g( int *array );
void testg() {
int array1[3]; g(array1); // correct, the array decays into & array[0]
int array2[2]; g(array2); // correct, the array decays again
int *p = array1; g( p ); // correct it is a pointer
}
Note that when you define a function that takes an array by value you are actually defining a function that takes a pointer by value and that the compiler will not check that the argument to the function call actually has that size. This is a known source of errors and the reason why most functions that take arrays also take a size parameter.
Lastly, you cannot create arrays dynamically, you can only acquire memory dynamically into pointers, so when you need a heap allocated array you are actually in need of a pointer into a heap allocated contiguous block o memory:
void test() {
int *p = new int[3];
// int array[3] = new int[3]; // error!! an array is not a pointer
delete p;
}
At the end this all means that they are not the same thing, but that you can always use an array in the place of a pointer and it will be automatically converted by the compiler into a pointer to the first element of the array. More often than not, people will refer to pointers into a block of contiguously memory (whether stack or heap allocated) as array.
In terms of implementation, arrays and pointers are the same. That is, arrays are simply implemented as pointers to the first element in the array. The difference between
No *v_nos;
and
No v_nos[3];
Is that the latter sets aside memory for 3 elements for that array, while the pointer would need to have memory allocated using malloc (or new).
You could still treat the second one as the pointer that it is though, for example *v_nos would give you the first element, &v_nos would give the address of the pointer.
You are correct, but it can also be used as an array :
v_nos = new Nos[10];
v_nos[5].whatever = something;
// etc
Yes, it declares (but does not initialise) a pointer to a No.
Its a pointer to a No struct.
If they are calling it an array, that pointer could point to the first member of an array of No structs
for example
No* nos= getNosArray();//pseudocode
*nos;//first element
*(nos+1)//2nd element;
Arrays and pointers are more or less interchangeable in C++. You can dereference an offset from a pointer - *(v_nos+2) - and it's effectively the same as indexing an array v_nos[2]. In fact you can use either notation, IIRC. Under the covers both examples tell the compiler to do the same thing: increment the pointer by 2 * the size of the pointed-at object, and then return what it finds at that location.
typedef struct NO
{
int x;
}_NO;
int main()
{
_NO* v_nos;
_NO *v_nos_array;
v_nos = new _NO(); // allocate mem for 1 struct
v_nos_array = new _NO[100]; allocate mem for 100 structs
for(1=0; 1<100; i++) v_nos_array[i].x = i; //five some value to 'x' of each struct
for(1=0; 1<100; i++) cout << v_nos_array[i].x << "\n";
}
hope you can extract out the meaning. Note that an array with a single element is still an array.
Related
I have this code declaring an array of pointers and assigning value of 5 to the location that the first pointer in the array points to:
int *p[10];
*p[0]=5;
However, this is showing an EXC_BAD_ACCESS error. I tried
int **p = new int *[10];
*p[0]=5;
But this is giving the same error. How do I assign a value to the location pointed by an element of my array of pointers? Thank you.
Before dereferencing the first pointer in the array, you need to initialize it to point to a valid memory location. For example:
int *p[10];
p[0] = new int;
*p[0] = 5;
Note that manual memory allocation at such level is almost certainly not what you want to use, except as a learning exercise, or as part of implementation of a larger structure. If you in fact want to an array of 10 integers, and access parts of it through a pointer, you can do it like this:
int array[10]; // allocate room for ten integers
array[0] = 5; // initialize the first one
int *first = &array[0]; // get a pointer to the first one
assert(*first == 5); // work with the pointer
If you do need an array of pointers, look into std::unique_ptr and std::shared_ptr to make sure they do not leak data in case of exceptions, early returns or forgotten delete.
I stumbled on this problem while tinkering with old school arrays. An interesting one though:
a[] = {1,2,3,4,5};
a[][] = {{1,2,3,4}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}}
Consider 2 scenarios:
1.)
void func(int *a) { //passing a 1D array
a[1] = 100; //modified an element here
delete a; //This would have no effect on the array outside this function.
}
2.)
void func(int (*a)[4]) { //passing a 2D array
a[1][2] = 100; //modified an element here of 2D array
delete a; //Would have an effect on the outside. Would delete a[0][0]'s memory outside.
}
Question is why?
In 1.) pointer shall point to an array variable memory hence, the delete signature won't clear the memory a[0]?
In 2.) the signature of parameter and passed variable match exactly hence the delete would indeed delete the memory held by local variable?
Any pointers here?
You're invoking undefined behavior on multiple levels. Calling delete on an array rather than delete[]...and calling any form of delete on an object not allocated with new.
Your program can do anything it wants.
If I want to dynamically allocate memory for array of pointers of int, how can I achieve this requirement?
Suppose I declare an array of pointers of int like this:
int (* mat)[];
Is there a way I can allocate memory for K number of pointers dynamically and assign it to mat? If I do
mat = new int * [K];
It gives error : cannot convert 'int**' to 'int (*)[]' in assignment. I understand this memory allocation is implicitly got converted to int **. Is there any way to allocate memory for above scenario?
Even when I try to assignment of statically allocated array of pointers of int to array of pointers of int, like this:
int (*mat)[] = NULL;
int (* array_pointers)[26];
mat = array_pointers;
Compilation gives this error: cannot convert 'int (*)[26]' to 'int (*)[]' in assignment.
Can someone please explain to me why this is an error or why it should be an error?
In C, int (* mat)[]; is a pointer to array of int with unspecified size (not an array of pointers). In C++ it is an error, the dimension cannot be omitted in C++.
Your question says new int *[K] so I assume this is really a C++ question. The expression new T[n] evaluates to a T * already, there is no implicit conversion.
The code to allocate an array of null pointers using new is:
int **mat = new int *[10]();
Then mat points to the first one of those. Another option (less commonly used) is:
int * (*mat)[10] = new int *[1][10]();
where *mat designates the entire array of 10 pointers.
NB. This sort of code is not useful for anything except demonstration purposes perhaps, whatever you are trying to do has a better solution.
In C and C++, in some cases, arrays and pointers are interchabgable.
int*[] decays in to int**.
To dynamically allocate an array, use:
int* mat;
// ...
mat = new int[size];
// ...
delete[] mat;
Note that you need to delete all memory you take with new, or else you'll leak memory.
It's not always easy to do.
C++ has a thing called RAII to help.
To use RAII (meaning all resources taken in a scope will be released when the scope ends), put the new in a classes constructor, and delete in the destructor.
The STL has some comtainers ready for you to use.
Look in to std::vector.
If you want an array of pointers as opposed to a dynamic array, the syntax is more like
int** arr = new int[size];
arr[i] = &val;
// ...
delete[] arr;
Don't forget to initialize each pointer in the array!
If size is known at compile time, this can be rewritten as:
std::array<int*, size> arr;
arr[i] = &val;
No need to delete, and it checks overflows.
If size is unknown at compile time, you can do:
std::vector<int*> arr;
arr.resize(size);
arr[i] = &val;
I understand that we use this when we need to give a pointer to an array of pointers in the dynamic memory but what I don't understand is that how this works in the stack.
Does this make an array of pointers in the stack too that is pointing to the array of pointers in the heap or does it make a single pointer in the stack that is pointing to the array of pointers in the heap? if yes, then what is the difference between
int **p = new int*[100]
and
int *p = new int[100]
Thanks in advance. I have been trying to understand this for a long time now and have read a lot of documentation online but I still don't understand this.
int **p declares a pointer on the stack which points to pointer(s) on the heap. Each of that pointer(s) point to an integer or array of integers on the heap.
This:
int **p = new int*[100];
means that you declared a pointer on the stack and initialized it so that it points to an array of 100 pointers on heap. For now each of that 100 pointers point nowhere. By "nowhere" I mean that they point neither to a valid chunk of memory, nor they are nullptrs. They are not initialized, thus they contain some garbage value which was in the memory before the pointers were allocated. You should assign something sensible to them in a loop before usage. Note that p[0] - p[99] pointers are not guaranteed to point to adjacent regions of memory if you assign return values of new to them. For example, if you allocate memory for each of them as p[i] = new int[200];, p[0][201] will not reference p[1][2], but will lead to an undefined behavior.
And this:
int *p = new int[100];
is a pointer on the stack which points to an array of 100 integers on the heap.
Don't worry, pointers and arrays in C are always a source of confusion. In general, when you declare an array of, say type int, you create a pointer of type int that points to the first element in a contiguous block of memory that will store ints. For example, if I have a simple array of ints using int *p_to_intarr = new int[3], I get this:
+++++++ <--------- p_to_intarr
| int |
+++++++
| int |
+++++++
| int |
+++++++
In general, if I want an array of type T, I create a pointer to type T like T *ptr_to_Tarr = new T[3].
So what if I want an array of array of ints? Lets just replace the T in with the type of an "array of ints" and this will give us an array of "array of ints". Well we just say in our first example that the type of an array of ints in int *, and so an array of array of ints would be: int* *ptr_to_arrayofintarr = new int*[3]. Note we just replaced the T with int star. This is often written more neatly as int **ptr_to_arrayofintarr = new int*[3].
So int **p could be a pointer to a 2d array. It could also be a reference to a 1d array; depends on the specific case :)
The new expression evaluates to a pointer of some type, pointing to memory that has been allocated in the free store (essentially the heap) but not necessarily in the free store. (It can still be in the free store depending on the context; for instance, consider an initialization-list in a constructor for an object being allocated in the free store.)
The object(s) initialized by new is/are of course in the free store.
In the assignment statements you've shown, you can see the type of the pointer returned by new on the left side of the equals sign, and the type of the free store object(s) to the right of the new. Thus the only object that is locally evaluated (i.e. might be on the stack) is, in the first case, a pointer-to-pointer-to-int, and in the second case, a pointer-to-int. The objects in free space are an array of pointers-to-ints in the first case and a simple array of ints in the second.
Note that just because the array in the first assignment consists of pointers doesn't mean that the pointers themselves actually point to anything yet; new does not magically recursively allocate free space for objects to be targeted by any pointers in an array it creates. (This wouldn't make much sense anyway.)
The ** means that you have a pointer to pointers. In more practical terms, it means you have a two-dimensional array.
Since each element of the array is also a pointer, you need to initialize those pointers as well:
for (int i = 0; i < 100; ++i)
p[i] = new int[200];
This initializes a 100x200 array. You can access the bottom-right corner with p[99][199].
When it's time to delete the pointer you have to reverse the process:
for (int i = 0; i < 100; ++i)
delete [] p[i];
delete [] p;
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