If i have array of pointer to an array of pointer to int
int **arrs = new int *[n];
and assign each element to new array of pointer to int
for i<n
arrs[i] = new int[size]
Now, when i try to get size of these arrays, give me wrong value
int size = sizeof(arrs[0])/sizeof(int);
It gives me wrong value.
So how can i get the right value ?
You can't. arrs[0] is a pointer, so sizeof(arrs[0]) gives the size of that pointer.
It comes as a surprise to some that there is no way to get the size of an array from only a pointer to that array. You have to store the size somewhere else.
In C++ the simplest and best solution is to use std::vector. Why reinvent the wheel? std::vector has everything you would want from a dynamic array, and should be the first choice in this situation.
Related
I am creating a 2D-Array in C++ and need to pass this array as a parameter in a function. In my function, I need to access an element from the array in order to save it as a value, i.e.:
int lowestPoint(int **arr, int x, int y, int n) {
minVal = *(*(arr+x)+y); // here is where I'm getting the exception
return minVal;
}
I've tried setting minVal to arr[X][Y] and have tried to pass the array in as other variations instead of just **arr but nothing seems to be working.
The array is initialized in my main function as int arr[x][y] and I pass it into another function by casting it as otherFunc(reinterpret_cast<int **>((*arr)[n]), n), and then from that function, send it to lowestPoint by calling int val = lowestPoint(arr,i,j,n). I think these calls could be problematic but I'm uncertain how to fix it - I really have no experience with 2D arrays in C++ and it's soo much simpler in Java. I keep getting an EXC_BAD_ACCESS error for the array, so if anyone has any idea how to fix that, I'd really appreciate it. Thanks!
EDIT:
"n" is the size of the array; for example if it's a 3x3 array, n = 3. I just initialized the array as int arr[n][n] and then stored elements. I know the actual array itself represents the correct value, it just can't access it once I send it to another function.
When you pass the array to the first function using reinterpret_cast((*arr)[n]), instead of passing the pointer to the actual array, you are passing the value in location [0][n] (by using (*arr)[n]) and casting it to **arr. So in essence you get a new array that points to a random location in memory that is equal to the content of that array slot.
I am not sure what you intended to do, but if you wanted to pass the actual array, just pass arr. If you planned to pass a sub-array, this method is incorrect altogether as you pass an offset inside an array and you will get skewed data.
Hope This helps,
Lior
I am trying to initialize a multidimensional array in batches and can't seem to make it work or find an example!
The dimensions I am working with are big enough that I don't want to specify them by hand!
More precisely :
int test[5][192];
for(int i = 0; i < 5; i++){
int temp[192] = {...};
test[i] = temp;
}
// use variable test here..
I want to use this method because the temp array is dynamicaly defined depending on variable i.
Is this type of initialization possible?
Should the temp array be in dynamic memory?
Since after the initialization I pass a reference to the first element of test to another function and I am not in control of how the other function passes over the elements I need to keep the data type of an array!
If you want to copy the values of temp array , instead of "=", you should use memory copy
memcpy( test[i], temp, sizeof(temp[192]));
Arrays do not have the copy assignment operator. So this is impossible with arrays.
If you will dynamically allocate each row then in any case you have to store somewhere the number of their elements. So even dynamically allocated arrays are not suitable in this case when the numbers of elements in each row can differ.
You should use standard container std::vector<std::vector<int>> instead.
You dont use the second dimension in the array for the test array. you just write test[], but you must write test[][].
I thing you don't must use the temp array. You can initialize you array direct, without using a temp array.
I'm not absolutly sure, but memcpy are just using for one diemnsionalarrays ant not for multidimensional arrays
if you know, Temp and test[i] are two pointer which point to memory
so if you print temp or test[i] you will see the address of where they start on memory.
in your code you lose the address of test[i] because you changed pointer test[i] to temp
and now both of them are pointing to the same place where temp begin on there!
The problem that I have is to create a specific matrix.
I have to use an array called for example ptr with x pointers. Each pointer in this array should point to a new array (in this case, an int array; each array is a new line in the matrix then).
All x arrays should be created with new; in the end, it should be possible to access the matrix with ptr[a][b] easily.
After a lot of trying and failing, I hope that someone can help me out.
Thank you in advance!
Since this is obviously homework, let me give you a better answer for your sake to go alongside the accepted one.
std::vector<std::vector<int>> matrix(10, std::vector<int>(10));
// ^ ^ ^
// Column count ______| |________________|
// |
// |___ Each column is
// initialized with
// a vector of size 10.
That's a 10x10 matrix. Since we're using vectors, the sizes are dynamic. For statically sized arrays, you can use std::array if you want. Also, here's the reference for std::vector.
If the number of pointers in the array is known, you could simply use a raw array of pointers to int:
int* my_array[10]; // 10 int*
Then you should allocate memory individually for each pointer in the array using usually a for loop:
for(int i=0; i<10; i++){
// each int* in the array will point to an area equivalent to 10 * sizeof(int)
my_array[i] = new int[10];
}
On the other hand, if you don't know the size of the array, then you need a pointer to pointers:
int** ptr_to_ptr = new int*[10];
Note that I am allocating space for 10 int* and not int.
Remember to deallocate the memory allocated above also for the internal pointers, once you don't need that memory anymore.
Title says it all more or less. When I need an (for the sake of this example) integer array for an unknown amount of values I know I can change it's size using new *array = new int[size]. Now my question is: If I have an array of a certain size, but I need to make it bigger, can I just use the new operator to expand it and will it still have all previously stored elements or would it be smarter to create a whole new array with a dynamic size, copy all elements from the previous array into the new one and delete[] the old array. Basically just swapping between the two arrays, whenever I need a new size.
Specifically I am asking whether or not this piece of code would work in the way it's intended to work
for(int i = 1; i < 10; i++){
int *array = new int[i];
array[i-1] = i;
}
My assumption is that this array will first be the size of 1 and store the value 1 at index 0. Then it will reallocate its size to 2 and store the value to at index 1 and so on until i is 9.
I guess to rephrase my question a bit better: Does an array initialized with new have to be populated with elements or will it copy the elements it had from before using the operator?
You can't resize the array in this way. You need to make a new array and then copy the old array into it. You can also try std::vector, which does what you want automatically.
If you want to use pointers rather than std::vector to change the size of your array, you can do it in this way.
int n = 100; // This will be the number of elements.
int *array1; // Pointer
array1 = new int[n]; // This will allocate your array with size n, so you will have 100 elements. You can combine this with the previous in int *array1 = new int[n];
So fill up the this array however you please...
Then you decide you want a 200 element array instead? You will need to create a different array in the same way.
int *array2 = new int[200];
You can use the for loop to copy array 1 into array 2. The for loop should iterate as many times as there are elements in array 1 (100).
for(int i = 0; i < 100; ++i)
array2[i] = array[1];
At this stage array2 is exactly the same as array1, but with 100 uninitialized elements at your disposal from [100] to [199].
You won't need array1 anymore, so at some point, you should call
delete [] array1;
Your assumption, by the way would not work, because on the first cycle of your loop, you create (or try to create) an array of i=1 element. Arrays start counting at 0, so your only single element is [0]. When i is at 0, what is i-1?
If you try to access array[-1], you'll probably crash. But why should you want to create 10 different arrays? new keyword creates an unrelated object, not overwrites the one with the same name.
Does an array initialized with new have to be populated with elements or will it copy the elements it had from before using the operator?
new[] allocates new array, completely independent from previous.
I know 3 ways to "make the array bigger":
As #ravi mentioned, don't mess with poinsters, use modern std::vector.
Make new array in new pointer, std::move elements from old array to the new one, and then delete[] old array.
Get rid of new[] & delete[], use old realloc with malloc & free.
You have to allocate new array and copy old array's data into that. This is how vector is implemented. Had there been better way of doing it, C++ standard community would have considered that.
I am a c++ newbie. While learning I came across this.
if I have a pointer like this
int (*a)[2][3]
cdecl.org describe this as declare a as pointer to array 2 of array 3 of int:
When I try
int x[2][3];
a = &x;
this works.
My question is how I can initialize a when using with new() say something like
a = new int [] [];
I tried some combinations but doesn't get it quite right.
Any help will be appreciated.
You will have to do it in two steps - first allocate an array of pointers to pointers(dynamically allocated arrays) and then, allocate each of them in turn. Overall I believe a better option is simply to use std::vector - that is the preferred C++ way of doing this kind of things.
Still here is an example on how to achieve what you want:
int a**;
a = new int*[2];
for (int i =0; i< 2;++i){
a[i] = new int[3]
}
... use them ...
// Don't forget to free the memory!
for (int i = 0; i< 2; ++i) {
delete [] a[i];
}
delete [] a;
EDIT: and as requested by Default - the vector version:
std::vector<std::vector<int> > a(2, std::vector<int>(3,0));
// Use a and C++ will take care to free the memory.
It's probably not the answer you're looking for, but what you
need is a new expression whose return type is (*)[2][3] This
is fairly simple to do; that's the return type of new int
[n][2][3], for example. Do this, and a will point to the
first element of an array of [2] of array of [3] int. A three
dimensional array, in sum.
The problem is that new doesn't return a pointer to the top
level array type; it returns a pointer to the first element of
the array. So if you do new int[2][3], the expression
allocates an array of 2 array of 3 int, but it returns
a pointer to an array of 3 int (int (*a)[3]), because in C++,
arrays are broken (for reasons of C compatibility). And there's
no way of forcing it to do otherwise. So if you want it to
return a pointer to a two dimensional array, you have to
allocate a three dimensional array. (The first dimension can be
1, so new [1][2][3] would do the trick, and effectively only
allocate a single [2][3].)
A better solution might be to wrap the array in a struct:
struct Array
{
int data[2][3];
};
You can then use new Array, and everything works as expected.
Except that the syntax needed to access the array will be
different.