Okay so I have:
char* arr[5];
and I have
char input[10];
and then:
int i = 0;
cin.getline(input, 10);
while(input[0] != 'z')
{
arr[i] = input;
cin.getline(input, 10);
i++;
}
the result is that every element in arr is the same because they are all pointers to input, but I want each element to point to char arrays that the input variable held at that given time.
result that this brings:
arr[0] = line beginning in 'z' (because that is what input currently is holding)
arr[1] = line beginning in 'z'
arr[2] = ... and so on
result that I want:
arr[0] = first line read in
arr[1] = second line read in
arr[2] = third line read in and so on...
I am confused about how I can get the elements to all point to new values instead of all be pointing to the same value.
If you want to take input 5 times,you can try this code segment
int i = 0;
while(i<5)
{
arr[i] = input;
cin.getline(input, 10);
i++;
}
this should work and you can get your "desired result" as you stated above.
Edit:
This will not work, as described in the comment. See example here: http://ideone.com/hUQGa7
What is required are different pointer values occupying each of the elements in arr. How to achieve those different pointer values is discussed in the other answers given.
Let's talk characters and pointers.
Given a character:
+---+
+ A +
+---+
A pointer to the character, char *, points to the character. That's it, nothing more.
An array of characters is a container that has slots for characters. A pointer to the array often points to the first character of the array. Here's where the problem comes in.
Many functions require a pointer, to the first character of the array, but either don't say that it's to the first character or require a pointer to a single character, assuming that the pointer is the first character in the array.
Pointers need something to Point at
You have allocated an array of pointers, but haven't allocated the memory for each pointer:
Array
+-----+ +----+---+---+
| | --> | | | |
| | +----+---+---+
+-----+
| | +----+---+---+
| | --> | | | |
| | +----+---+---+
+-----+
The content of the array are pointer. So you will need to allocate memory and place the pointer into the array:
arr[0] = new char [11]; // +1 for the nul terminator character.
char text[33];
arr[1] = text;
So what you aim to do is:
cin.getline(arr[0], 10);
cin.getline(arr[1], 33);
Strings are soooo much easier to deal with. They manage their own memory:
std::string array_text[5]; // An array of 5 string.
getline(cin, array_text[0]);
The next step is to use a vector and you are all caught up:
std::vector< std::string > text_vector(5); // Pre-allocate 5 slots.
getline(cin.text_vector[2]);
You have to copy the data of input everytime.
You can do like this in while loop:
while(input[0] != 'z')
{
arr[i] = new char[strlen(input)];
strcpy(arr[i], input);
cin.getline(input, 10);
i++;
}
And since you have defined arr to be of length 5. So you have to check in the while loop that i doesn't exceed the value 5. i<5.
Related
Activity solution[a][b];
...
Activity **mother = solution;
I want to convert 2D array of objects to pointer-to-pointer. How can I do this;
I searched it on google. however I found only one dimension array example.
A mere conversion won't help you here. There's no compatibility of any kind between 2D array type and pointer-to-pointer type. Such conversion would make no sense.
If you really really need to do that, you have to introduce an extra intermediate "row index" array, which will bridge the gap between 2D array semantics and pointer-to-pointer semantics
Activity solution[a][b];
Activity *solution_rows[a] = { solution[0], solution[1] /* and so on */ };
Activity **mother = solution_rows;
Now accessing mother[i][j] will give you access to solution[i][j].
The reason you can do this for one-dimensional arrays and not two-dimensional arrays has to do with the way in which the actual array elements are stored in memory. For one-dimensional arrays, all of the elements are stored consecutively, so the expression array[i] is equivalent to the expression *(array + i). As you can see, the array size is not needed to perform an array index operation. However, for two-dimensional arrays, the elements are stored in "row major" order, meaning that all of the elements in the zeroth row are stored first, followed by the elements in the first row, followed by the elements in the second row, etc. Therefore, the expression array[i][j] is equivalent to *(array + (i * ROW_SIZE) + j), where ROW_SIZE is the number of elements in each row. Therefore, the array's row size is needed to perform an array index operation, and casting the array variable to a pointer loses that information.
This is c++! Everything is possible! But a this is c++ so it requires some level of understanding.
To that end let's start with a simple example of 2 1-dimensional arrays: char firstName[4] = { 'J', 'o', 'n', '\0' } and char lastName[4] = { 'M', 'e', 'e', '\0' } Let's look at a possible memory layout here:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543210 | 0x4A | <- firstName[0] - 'J'
| 0x76543211 | 0x6F | <- firstName[1] - 'o'
| 0x76543212 | 0x6E | <- firstName[2] - 'n'
| 0x76543213 | 0x00 | <- firstName[3] - '\0'
+------------+-------+
| 0x76543214 | 0x4D | <- lastName[0] - 'M'
| 0x76543215 | 0x65 | <- lastName[1] - 'e'
| 0x76543216 | 0x65 | <- lastName[2] - 'e'
| 0x76543217 | 0x00 | <- lastName[3] - '\0'
+------------+-------+
Given this memory layout if you were to do cout << firstName << ' ' << lastName you'd get:
0x76543210 0x76543214
These arrays are really just a pointer to their first element! This illustrates Array to Pointer Decay, which you can read more about here: http://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
Before we move on there's something important here to note, chars take up exactly 1-byte so the address of each subsequent char in the array will simply be the next address. That's leveraged by the Subscript Operator in this way: firstName[1] is equivalent to *(firstName + 1). This is true for chars but is also true for any other type which takes up more than 1-byte. Let's take for example: short siArray = { 1, 2, 3, 4 }, a possible memory layout of siArray would look like:
+------------+--------+
| Address | Value |
+------------+--------+
| 0x76543218 | 0x0001 | <- siArray[0] - 1
| 0x7654321A | 0x0002 | <- siArray[1] - 2
| 0x7654321C | 0x0003 | <- siArray[2] - 3
| 0x7654321E | 0x0004 | <- siArray[3] - 4
+------------+--------+
Even though cout << siArray << ' ' << &(siArray[1]) will output:
0x76543218 0x7654321A
*(siArray + 1) will still index the same element of siArray as siArray[1]. This is because when doing pointer arithmetic c++ considers the type of the address being operated on, thus incrementing a short* will actually increase the address by sizeof(short). You can read more about pointer arithmetic here: http://en.cppreference.com/w/cpp/language/operator_arithmetic
Lastly let's look at how c++ stores 2-dimensional arrays. Given: char name[2][4] = { { 'J', 'o', 'n', '\0' }, { 'M', 'e', 'e', '\0' } } a possible memory layout would be:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543220 | 0x4A | <- name[0][0] - 'J'
| 0x76543221 | 0x6F | <- name[0][1] - 'o'
| 0x76543222 | 0x6E | <- name[0][2] - 'n'
| 0x76543223 | 0x00 | <- name[0][3] - '\0'
| 0x76543224 | 0x4D | <- name[1][0] - 'M'
| 0x76543225 | 0x65 | <- name[1][1] - 'e'
| 0x76543226 | 0x65 | <- name[1][2] - 'e'
| 0x76543227 | 0x00 | <- name[1][3] - '\0'
+------------+-------+
Since we know an 1-dimensional array value is really just a pointer, we can see from this memory layout that name[0] is not a pointer, it's just the first character of the first array. Thus name does not contain 2 1-dimensional array pointers, but contains the contents of the 2 arrays. (Incidentally on a 32-bit machine not storing the pointers saves 8-bytes of memory, which is pretty substantial for an 8-byte 2-dimensional array.) Thus trying to treat name as a char** would try to use the characters as a pointer.
Having understood this we really just need to avoid using c++'s pointer arithmetic to find dereference the value. To do that we'll need to work with a char* so that adding 1 is really just adding 1. So for example:
const short si2DArray[2][3] = { { 11, 12, 13 }, { 21, 22, 23 } };
const auto psi2DPointer = reinterpret_cast<const char*>(si2DArray);
for(auto i = 0U; i < size(si2DArray); ++i) {
for(auto j = 0U; j < size(*si2DArray); ++j) {
cout << *reinterpret_cast<const short*>(psi2DPointer + i * sizeof(*si2DArray) + j * sizeof(**si2DArray)) << '\t';
}
cout << endl;
}
Live Example
Note that in this example even though I reference si2DArray thought psi2DPointer I'm still using information from si2DArray to do the indexing, namely:
How many arrays are in the major dimension: size(si2DArray)
How many elements are in the minor dimension: size(*si2DArray)
What is the size in memory of the minor dimension: sizeof(*si2DArray)
What is the element type of the array: sizeof(**si2DArray)
You can thus see that the loss of information from converting from an array to a pointer is substantial. You may be tempted to preserve the element type, thereby also simplifying the pointer arithmetic. It's worthwhile to note that only a conversion to char* is considered defined behavior by reinterpret_cast: http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
I want to convert 2D array of objects to pointer-to-pointer. How can I do this?
Why? Is it because an interface expects a pointer to pointers?
If so, you'll need to create a new array that contains those pointers.
Activity solution[a][b];
Activity* solutionPtrs[a];
for (int i = 0; i < a; ++i)
solutionPtrs[a] = solution[a];
Activity** mother = solutionPtrs;
Why can't you just cast a 2D array of T to T**? Well, because they have nothing to do with one another!
You can cast a T[a] to a T* because you get a pointer to the first element of the array.
You can do this with 2D arrays as well, but if you have a T[a][b] then it decays to a (T[b])* because a 2D array is not an array of pointers, it's an array of arrays.
Not sure if you were looking for something like this. You should provide more details about what you want to achieve. They are fundamentally different types. One solution is to below.
For the record, if someone finds it useful:
// define matrix
double A[3][3] = {
{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}
};
// allocate memory
double ** A_ptr = (double **) malloc(sizeof (double *) * 3);
for (int i = 0; i < 3; i++)
A_ptr[i] = (double *) malloc(sizeof (double) * 3);
// copy matrix
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A_ptr[i][j] = A[i][j];
printf(" %f ", A_ptr[i][j]);
}
}
You can't. They are fundamentally different types.
I've searched through many articles on here and have self-tested this concept with my own code. My question is to satisfy my own curiosity and maybe help others as I cannot find a answer describing this concept in particular. My textbook (teaching C++) describes a C-string variable:
A C-string variable is an array of characters. The following array declaration provides a C-string variable "s" capable of storing a
C-string value with nine or fewer characters:
char s[10];
The 10 is for the nine letters in the string plus the null character '\0' to mark the end of the string. Like any other partially filled
array, a C-string variable uses positions starting at indexed variable
0 through as many as are needed.
I'm trying to understand the above. If the array size is 10, wouldn't the total storage size be 11? i.e. 0-10 = 11 spaces. If the \0 character occupies one space, then we'd still be able to store 10 characters and not 9 as per the book.
In my own testing, I declared a character array test[4] and stored the word "cat" in the array. When looking at individual positions within the array, I can see individual characters at each index i.e:
test[0] = c
test[1] = a
test[2] = t
test[3] =
test[4] =
Why do we need 2 additional slots in the character array and not 1?
An array with size N has indexes starting at 0 and ending with N-1. It does not have an element with index N.
With your example of char test[4], the array has indexes 0, 1, 2, and 3. Attempting to access index 4 is going off the end of the array. C and C++ do no prevent you from doing so, and attempting to do so invokes undefined behavior.
You can look at an array as a group of variables of the same type and size which are consecutive in memory one next to the other.
Arrays are indexed from 0 as the first element to the n - 1 as the last element. So you can access any element just using an index.
Trying to access an array with an index i >= n or a negative index i < 0 Will issue in undefined behavior.
Arrays of characters need to set the last element as a NULL character \0.
Here is an example:
char c[5] = "Hello"; // Error
Above c has 5 elements and \0 so it is 6 Byte long. So to correct it:
char c[6] = "Hello"; // Null character added automatically
// char c[] = "Hello";
Look at this example:
char text[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
Above in a such initialization you must add the null terminator character '\0' otherwise you'll get a garbage characters at the end of your string.
std::cout << text[0]; // H which is the first element
std::cout << text[6 - 1 - 1]; // o which is the last character in the array.
arrays of other types other than characters need not to add a null terminator and the number of elements is n but indexing is the same 0 through n - 1;
int array[5] = {4, 5, 9, 22, 16};
std::cout << array[0]; // 4
std::cout << array[5 - 1]; // 16
I think your problem comes from the misconception of how you access the memory.
s[n] refers at accessing the value pointed by the pointer s plus n blocks in memory, it can also be written *(s + n)
So basically, declaring
char s[4];
and setting cat in it, you will get this layout in memory
+---+
s: | c | s[0] also (s + 0)
+---+
| a | s[1] also (s + 1)
+---+
| t | s[2] also (s + 2)
+---+
|\0 | s[3] also (s + 3)
+---+
| ? | s[4] also (s + 4)
+---+
| ? | s[5] also (s + 5)
+---+
| ? | s[6] also (s + 6)
+---+
| ? | s[7] also (s + 7)
+---+
| ? | s[8] also (s + 8)
+---+
| ? | s[9] also (s + 9)
+---+
The ? stand for a variable which we aren't sure of the value.
You CAN access it, you can even modify it sometimes.
But the behavior of this isn't clear and can be undefined.
For your example s[4] can change each time the executable is executed.
char s[10]; had valid indices from 0 to 9 and not 0 to 10 as you said.
A C-string variable is an array of characters.
This is slightly misleading. A C string is a sequence of character values followed by a 0-valued terminator. For example, the string "Hello" is represented as the sequence {'H','e', 'l', 'l', 'o', 0}. The presence of the 0 terminator makes the character sequence a string. All C string handling functions (strcat, strcmp, strcpy, strchr, etc.) assume the presence of that terminator; if the terminator isn't there, those routines will not function properly.
Strings are stored in arrays of character type (char for ASCII, EBCDIC, or UTF-8 strings or wchar_t for "wide" strings1). Multiple strings may be stored in a single array if there's sufficient space. A 10-element array may store a single 9-character string, or two 4 character strings, or 5 one-character strings. Remember that to store an N-character string you need N+1 array elements to account for the terminator.
I'm trying to understand the above. If the array size is 10, wouldn't the total storage size be 11? i.e. 0-10 = 11 spaces.
Total storage size is 10, but array elements are indexed from 0 to 9. Given the declaration
char foo[10];
you get the following layout in memory:
+---+
foo: | | foo[0]
+---+
| | foo[1]
+---+
| | foo[2]
+---+
| | foo[3]
+---+
| | foo[4]
+---+
| | foo[5]
+---+
| | foo[6]
+---+
| | foo[7]
+---+
| | foo[8]
+---+
| | foo[9]
+---+
For any N-element array, individual elements are indexed from 0 through N-1.
Remember that in C, the array subscript operation a[i] is defined as *(a + i) - given a starting address a2, offset i elements (not bytes!!!) from that address and dereference the result. The first element is stored at a, the second element is stored at a + 1, the third at a + 2, etc.
wchar_t was introduced to represent character sets outside the ranges defined by ASCII or EBCDIC, so it's wider than the `char` type (often the width of two `char`s). With the advent of schemes like UTF-8 to represent non-English character sets, it's not that useful and I don't see it used very often.
At some point, you're going to hear someone say "an array is just a pointer". This is not correct. Under most circumstances, an expression of array type will be converted ("decay") to an expression of pointer type, and the value of the expression will be the address of the first element in the array. The array object itself is not a pointer, nor does it set aside any space for a pointer value.
char test[4] is the definition of your array, it means your array's size is four, but you can only use the spaces: test[0], test[1], test[2], test[3].
You can go to http://www.cplusplus.com/doc/tutorial/arrays/ to learn more about Arrays of c++.
char *t=new char();
and
char *t=new char[102];
as my code was accepted by using the latter one?
//BISHOPS SPOJ
char *t=new char();
Allocates memory for a single character, and calls the default constructor.
char *t=new char[102];
Creates an array of 102 chars and calls the default constructor.
As the default constructor for POD types is nothing, the difference is the amount of memory allocated (single char vs array of char)
Actually both are pointers on char, but second is pointer to char array.
Which allows you to store 102 characters into the array.
char *t=new char[102];
0 1 2 3 101
+---+---+---+---+ ... +---+
| | | | | |
+---+---+---+---+ ... +---+
^
|
-----------------------------+---+
| * |
+---+
t
It allows you to dereference these indexes 0-101.
While first one allows you to store only one character.
char *t=new char();
0
+---+
| |
+---+
^
|
-----------------------------+---+
| * |
+---+
t
Where dereferencing other index than 0 would lead to access outside of bounds and undefined behavior.
Deleting
To delete an character char *t=new char();
delete t;
Where to delete an array char *t=new char[102]; you have to write empty brackes, to explicitly say its an array.
delete [] t;
Same with these codes
char *t = new char[10]; // Poitner to array of 10 characters
char *t = new char(10); // Pointer to one character with value of 10
Memory initialialization
char *t = new char(); // default initialized (ie nothing happens)
char *t = new char(10); // zero initialized (ie set to 0)
Arrays:
char *t = new char[10]; // default initialized (ie nothing happens)
char *t = new char[10](); // zero initialized (ie all elements set to 0)
Questions regarding, well, ultimately pointers to pointers (I suspect). Please read the questions posed in the commented code:
void doodah(char* a);
int main() {
char d[] = "message"; // one way of assigning a string.
// char* d = "message"; // another way of assigning a string, but REM'ed out for now.
cout << d << endl; // d appears not to be a pointer because cout outputs "message", and not an address. Why is this?
doodah(d); // a function call.
}
void doodah(char* a) {
cout << a << endl; // this outputs "message" - but why?! What does 'a' mean in this context?
// cout << *a << endl; // this outputs "m" - but why?! REM'ed out for now.
}
I am utterly confused! Please help.
cout knows how to output strings when given a char *. It does not attempt to print the pointer value itself.
An array is a bunch of objects next to each other somewhere in memory. The variable you've set the array to is actually secretly a pointer to the first item in that array (shhh!).
The biggest difference between char *c and char c[] is that the latter will be a const pointer, while the former is free to change. Also, C-Strings, like the one you have set there, are null terminated, meaning that the array ends in a binary 0 so things like cout will know when to stop iterating (this is also known as a one pass last).
For more information, you can read up on this question.
This is what the pointer a looks like in memory:
-------------------------------------------------------------
| | 'm' | 'e' | 's' | 's' | 'a' | 'g' | 'e' | '\0' |
| ^ |
| | |
| --- |
| |a| |
| --- |
-------------------------------------------------------------
a is a pointer to the first element of the string. When used in the stream inserter (operator<<()) the compiler will match it with the overload that takes a stream on its left hand side and a pointer to a character on its right hand side. It will then attempt to print every character until it reaches the null byte ('\0') by evaluating characters at incremental addresses from a.
The stream prints addresses through the overload that takes a void* on its righthand side. You can cast your pointer to a void* or use the standard-provided std::addressof() function as well:
std::cout << std::addressof(a);
Activity solution[a][b];
...
Activity **mother = solution;
I want to convert 2D array of objects to pointer-to-pointer. How can I do this;
I searched it on google. however I found only one dimension array example.
A mere conversion won't help you here. There's no compatibility of any kind between 2D array type and pointer-to-pointer type. Such conversion would make no sense.
If you really really need to do that, you have to introduce an extra intermediate "row index" array, which will bridge the gap between 2D array semantics and pointer-to-pointer semantics
Activity solution[a][b];
Activity *solution_rows[a] = { solution[0], solution[1] /* and so on */ };
Activity **mother = solution_rows;
Now accessing mother[i][j] will give you access to solution[i][j].
The reason you can do this for one-dimensional arrays and not two-dimensional arrays has to do with the way in which the actual array elements are stored in memory. For one-dimensional arrays, all of the elements are stored consecutively, so the expression array[i] is equivalent to the expression *(array + i). As you can see, the array size is not needed to perform an array index operation. However, for two-dimensional arrays, the elements are stored in "row major" order, meaning that all of the elements in the zeroth row are stored first, followed by the elements in the first row, followed by the elements in the second row, etc. Therefore, the expression array[i][j] is equivalent to *(array + (i * ROW_SIZE) + j), where ROW_SIZE is the number of elements in each row. Therefore, the array's row size is needed to perform an array index operation, and casting the array variable to a pointer loses that information.
This is c++! Everything is possible! But a this is c++ so it requires some level of understanding.
To that end let's start with a simple example of 2 1-dimensional arrays: char firstName[4] = { 'J', 'o', 'n', '\0' } and char lastName[4] = { 'M', 'e', 'e', '\0' } Let's look at a possible memory layout here:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543210 | 0x4A | <- firstName[0] - 'J'
| 0x76543211 | 0x6F | <- firstName[1] - 'o'
| 0x76543212 | 0x6E | <- firstName[2] - 'n'
| 0x76543213 | 0x00 | <- firstName[3] - '\0'
+------------+-------+
| 0x76543214 | 0x4D | <- lastName[0] - 'M'
| 0x76543215 | 0x65 | <- lastName[1] - 'e'
| 0x76543216 | 0x65 | <- lastName[2] - 'e'
| 0x76543217 | 0x00 | <- lastName[3] - '\0'
+------------+-------+
Given this memory layout if you were to do cout << firstName << ' ' << lastName you'd get:
0x76543210 0x76543214
These arrays are really just a pointer to their first element! This illustrates Array to Pointer Decay, which you can read more about here: http://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
Before we move on there's something important here to note, chars take up exactly 1-byte so the address of each subsequent char in the array will simply be the next address. That's leveraged by the Subscript Operator in this way: firstName[1] is equivalent to *(firstName + 1). This is true for chars but is also true for any other type which takes up more than 1-byte. Let's take for example: short siArray = { 1, 2, 3, 4 }, a possible memory layout of siArray would look like:
+------------+--------+
| Address | Value |
+------------+--------+
| 0x76543218 | 0x0001 | <- siArray[0] - 1
| 0x7654321A | 0x0002 | <- siArray[1] - 2
| 0x7654321C | 0x0003 | <- siArray[2] - 3
| 0x7654321E | 0x0004 | <- siArray[3] - 4
+------------+--------+
Even though cout << siArray << ' ' << &(siArray[1]) will output:
0x76543218 0x7654321A
*(siArray + 1) will still index the same element of siArray as siArray[1]. This is because when doing pointer arithmetic c++ considers the type of the address being operated on, thus incrementing a short* will actually increase the address by sizeof(short). You can read more about pointer arithmetic here: http://en.cppreference.com/w/cpp/language/operator_arithmetic
Lastly let's look at how c++ stores 2-dimensional arrays. Given: char name[2][4] = { { 'J', 'o', 'n', '\0' }, { 'M', 'e', 'e', '\0' } } a possible memory layout would be:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543220 | 0x4A | <- name[0][0] - 'J'
| 0x76543221 | 0x6F | <- name[0][1] - 'o'
| 0x76543222 | 0x6E | <- name[0][2] - 'n'
| 0x76543223 | 0x00 | <- name[0][3] - '\0'
| 0x76543224 | 0x4D | <- name[1][0] - 'M'
| 0x76543225 | 0x65 | <- name[1][1] - 'e'
| 0x76543226 | 0x65 | <- name[1][2] - 'e'
| 0x76543227 | 0x00 | <- name[1][3] - '\0'
+------------+-------+
Since we know an 1-dimensional array value is really just a pointer, we can see from this memory layout that name[0] is not a pointer, it's just the first character of the first array. Thus name does not contain 2 1-dimensional array pointers, but contains the contents of the 2 arrays. (Incidentally on a 32-bit machine not storing the pointers saves 8-bytes of memory, which is pretty substantial for an 8-byte 2-dimensional array.) Thus trying to treat name as a char** would try to use the characters as a pointer.
Having understood this we really just need to avoid using c++'s pointer arithmetic to find dereference the value. To do that we'll need to work with a char* so that adding 1 is really just adding 1. So for example:
const short si2DArray[2][3] = { { 11, 12, 13 }, { 21, 22, 23 } };
const auto psi2DPointer = reinterpret_cast<const char*>(si2DArray);
for(auto i = 0U; i < size(si2DArray); ++i) {
for(auto j = 0U; j < size(*si2DArray); ++j) {
cout << *reinterpret_cast<const short*>(psi2DPointer + i * sizeof(*si2DArray) + j * sizeof(**si2DArray)) << '\t';
}
cout << endl;
}
Live Example
Note that in this example even though I reference si2DArray thought psi2DPointer I'm still using information from si2DArray to do the indexing, namely:
How many arrays are in the major dimension: size(si2DArray)
How many elements are in the minor dimension: size(*si2DArray)
What is the size in memory of the minor dimension: sizeof(*si2DArray)
What is the element type of the array: sizeof(**si2DArray)
You can thus see that the loss of information from converting from an array to a pointer is substantial. You may be tempted to preserve the element type, thereby also simplifying the pointer arithmetic. It's worthwhile to note that only a conversion to char* is considered defined behavior by reinterpret_cast: http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
I want to convert 2D array of objects to pointer-to-pointer. How can I do this?
Why? Is it because an interface expects a pointer to pointers?
If so, you'll need to create a new array that contains those pointers.
Activity solution[a][b];
Activity* solutionPtrs[a];
for (int i = 0; i < a; ++i)
solutionPtrs[a] = solution[a];
Activity** mother = solutionPtrs;
Why can't you just cast a 2D array of T to T**? Well, because they have nothing to do with one another!
You can cast a T[a] to a T* because you get a pointer to the first element of the array.
You can do this with 2D arrays as well, but if you have a T[a][b] then it decays to a (T[b])* because a 2D array is not an array of pointers, it's an array of arrays.
Not sure if you were looking for something like this. You should provide more details about what you want to achieve. They are fundamentally different types. One solution is to below.
For the record, if someone finds it useful:
// define matrix
double A[3][3] = {
{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}
};
// allocate memory
double ** A_ptr = (double **) malloc(sizeof (double *) * 3);
for (int i = 0; i < 3; i++)
A_ptr[i] = (double *) malloc(sizeof (double) * 3);
// copy matrix
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A_ptr[i][j] = A[i][j];
printf(" %f ", A_ptr[i][j]);
}
}
You can't. They are fundamentally different types.