How do i declare a 2d array using the 'new' operator? My book says this:
int (*p)[4];
p=new[3][4];
but it doesn't make sense to me. p is a pointer to an array of 4 ints, so how can it be made to point to a 2d array?
How do i declare a 2d array using the 'new' operator? My book says this:
int (*p)[4];
p=new[3][4];
but it doesn't make sense to me. p is a pointer to an array of 4 ints, so how can it be made to point to a 2d array?
It seems you need pointer to pointer. EDIT: Well, to be more exact, the following example creates an array of pointers to arrays.
First do:
int **p = new int*[NUM];
Here you've created array of pointers. Now you need to create another array for every of them. That you can do this way:
for(int i = 0; i < NUM; i++)
{
p[i] = new int[ANOTHER_NUM];
}
For deallocation you do similar, but in reverse way:
for(int i = 0; i < NUM; i++)
{
delete[] p[i];
}
And finally:
delete[] p;
Now you can work with it. This way you can create N-dimensional array, just add more '*'. If you have any other particular question, ask in the comments, please.
But, generally, for further info I recommend you to try Google first with questions like "2D array in C++" or "dynamic allocation of 2D array C++", i. e. this query.
Other answers cover having a pointer array for your rows, with a pointer to an int
array per row. Another option is to simply allocate a 1-D array big enough to hold all the 2-D array's elements:
int* p = new int [3 * 4];
Then instead of using the p[r][c]
syntax, you use p[r * kNumCols + c]
. In this example, kNumCols = 4
. This is generally what's done in LAPACK-style number crunching, since it keeps things contiguous in memory and you don't need to allocate so many memory blocks.
Note: This generally is not slower than the alternative in practice, because the row offset calculation is moved out of the loop by the common subexpression optimization. Also, many optimizers know to look for this pattern. Further, by keeping your data co-located in a single block of memory, the data is more likely to stay in cache.
In C++, you could implement the p[][]
notation with a helper template class:
template<class T>
class Array2DPtrRow
{public:
Row(T* row_): row(row_) {}
operator T*() { return row; }
T& operator [](size_t c) { return row[c]; }
private:
T* row;
};
template<class T, size_t NC>
class Array2DPtr
{public:
Array2DPtr(T* buf_): buf(buf_) {}
operator T*() { return buf; }
Array2DPtrRow<T> operator [](size_t r)
{ return Array2DPtrRow<T>(buf + NC * r); }
private:
T* buf;
};
This optimizes down to the same code as above, but allows you to use [][]
notation and requires you to know your array dimensions at compile time. Usage example:
Array2DPtr<int, 4> p(new int[3 * 4]);
p[1][2];
This could be converted to make NC into a class member instead of a template parameter, but then the final object isn't just a pointer any more:
template<class T>
class Array2DPtr
{public:
Array2DPtr(T* buf_, size_t nc_): buf(buf_), nc(nc_) {}
operator T*() { return buf; }
Array2DPtrRow<T> operator [](size_t r)
{ return Array2DPtrRow<T>(buf + nc * r); }
private:
T* buf;
size_t nc;
};
Array2DPtr<int> p(new int[3 * 4], 4);
p[1][2];
Note that none of these classes need copy constructors, assignment operators, or destructors because they don't take ownership of the pointed-to memory any more than a regular pointer does. So to release the memory, you still need to do:
delete[] p;
Or if your compiler can't figure it out:
delete[] (int*)p;
To actually answer the question:
Remember that an array is equivalent to a pointer to the first element of the array, so for instance you can write:
char str[14] = "Hello, world!";
char *ptr = str;
This works for a two-dimensional array as well.
int (*p)[4];
declares a pointer to the first element of a two-dimensional array. p
can then be pointed at any two-dimensional array, as long as its second dimension is 4, so for instance you could write
int arr[3][4];
int (*p)[4] = arr;
Of course you can also allocate the memory dynamically:
int (*p)[4] = new int[3][4];
Again, the second dimension has to be 4, but you can vary the first dimension.
There are several ways to declare multidimensional arrays in C.
You can declare p
explicitly as a 2D array:
int p[3][4]; // All of p resides on the stack.
(Note that new
isn't required here for basic types unless you're using C++ and want to allocate them on the heap.)
Or you can declare it as a vector (1D array) of pointers, and then allocate memory for each vector:
int *p[3]; // The vector addresses reside on the stack.
for (int i=0; i<3; i++) {
p[i] = malloc(4 * sizeof(int)); // Each element resides on the heap.
}
// You can now access p as p[j][k] as if it were a 2D array.
for (int i=0; i<3; i++) {
free p[i];
}
Or, if you don't know either dimension, you can allocate the entire 2D array dynamically:
#define WIDTH 3
#define HEIGHT 4
int **p; // Base address resides on the stack.
p = malloc(WIDTH * sizeof(int *)); // Pointers to vectors reside on the heap.
for (int i=0; i<WIDTH; i++) {
p[i] = malloc(HEIGHT * sizeof(int)); // Data values reside on the heap.
}
// You can now access p as p[j][k] as if it were a 2D array.
// Release the memory that was allocated to each vector.
for (int i=0; i<WIDTH; i++) {
free(p[i]);
}
// Release the memory that was allocated to the initial pointer.
free(p);
You need something like this
int **array_ptr; //two * are needed because it is a pointer to a pointer
array_ptr=new int*[firstnumber]; //creates a new array of pointers to int objects
for(int i=0; i<firstnumber; ++i)
array_ptr[i]=new int[secondnumber];
There's already a good answer but I wanted to allocate a 2d array without using (new, delete). So I used a std::vector instead.
std::vector<std::vector<double>> A;
A.resize(Col);
for(int i=0; i<Col; i++)
{
A[i].resize(Row);
}