I have a class that has a large 2 dimensional array in it. It used to be a dynamic array allocated on the heap and now it is statically sized which I prefer.
private:
int fontTextureCoords_[100][7];
I had to add the type casting to the the accessor in order to return the array for access outside the class which is currently working okay, but I'm not sure it is safe or the correct way to handle this.
public:
inline int **getFontTextureCoords()
{
return (int**)fontTextureCoords_;
}
Is this safe / the correct way to do this or is there a more preferred method for returning a pointer to a multi-dimensional array?
That's not the correct way to do that and shouldn't compile. A 2d array is not convertible to a pointer to pointer. You'd have to return a pointer to an array, which is easiest to write using a typedef:
using T = int[7];
inline T* getFontTextureCoords() { return fontTextureCoords_; }
Although it'd be much better to just return a reference the full array:
using T = int[100][7];
inline T& getFontTextureCoords() { return fontTextureCoords_; }
You could also just std::array<std::array<int, 7>, 100>.
Maybe this diagram shows you the difference between the two types of multi-dimensional array declarations. (Sometime people don't understand this.)
The first one says a is a single block of 100 consecutive 7-int chunks, or 700 ints total, all together in one piece.
The second says a is an array of pointers, where each pointer points to a different chunk of ints, scattered all over memory.
The compiler needs to know this, because if you write a[i][j] it has to generate totally different code.
Casting an array such as int fontTextureCoords_[100][7]; to an int** is not right. It leads to undefined behavior.
If it is not too much, change getFontTextureCoords to:
inline int (*getFontTextureCoords()) [7]
{
return fontTextureCoords_;
}
and use it as:
int (*ptr)[7] = getFontTextureCoords();
If you have the option of using std::vector or std::array, it will be better to use them.
There are no multi-dimensional arrays in C/C++. There are only single dimenstional arrays. You can have a single-dimensional array, with every element of it being another single dimensional array. While there seem to be no difference, it is there and is very important.
This is exactly way transitive logic doesn not work. Everybody has gone through it. 'If single-dimensional arrays are passed as a pointer to the first elelement, 2-D arrays should be passed as a pointer to pointer to first element, etc'. But since it is not a two-dimensional array, but array of arrays, the logic can not be applied.
You can reason about it in the following way. Let's say, you have an array of types X.
X x[10];
How do you access element number 5? Easy -
x[5] = 42;
But what compiler does when it sees it? It does approximately this:
*(&x[0] + 5) = 42;
So it takes the address of the first element, and adds 5 to it to get to the address of your 5th element. But what adding 5 means? In bytes, how many bytes should be skipped from address of beginning of the array to arrive at requested memory location? Of course, 5 * sizeof(X). Now, if you have '2-D' array, declared like this:
X x[2][3];
And you try to work with it through the pointer to pointer:
px = (X**)x;
px[3][4] = 42;
Remember, to genereate the code for [][], compiler needs to express in the way of *(px + ). And something has to be the size of the array (as elements of your array are arrays). But you need to know array size for this, and as you can see, your px does not have any array size encoded in it. The only size it know is size of X, which is not enough.
Hope it makes sense, and explains why you can't use int** instead of x[][].
Related
I want to know whether a pointer is pointing to an array or single integer. I have a function which takes two pointer (int and char) as input and tell whether a pointer is pointing to an array or single integer.
pointer=pointer+4;
pointer1=pointer1+4;
Is this a good idea?
Like others have said here, C doesn't know what a pointer is pointing to. However if you should choose to go down this path, you could put a sentinel value in the integer or first position in the array to indicate what it is...
#define ARRAY_SENTINEL -1
int x = 0;
int x_array[3] = {ARRAY_SENTINEL, 7, 11};
pointer = &x_array[0];
if (*pointer == ARRAY_SENTINEL)
{
// do some crazy stuff
}
pointer = &x;
if (*pointer != ARRAY_SENTINEL)
{
// do some more crazy stuff
}
That's not a good idea. Using just raw pointers there's no way to know if they point to an array or a single value.
A pointer that is being used as an array and a pointer to a single values are identical - they're both just a memory address - so theres no information to use to distinguish between them. If you post what you want to ultimately do there might be a solution that doesn't rely on comparing pointers to arrays and single values.
Actually pointers point to a piece of memory, not integers or arrays. It is not possible to distinguish if an integer is single variable or the integer is an element of array, both will look exactly the same in memory.
Can you use some C++ data structures, std::vector for example?
For C++ questions, the answer is simple. Do not use C-style dynamic arrays in C++. Whenever you need a C-style dynamic array, you should use std::vector.
This way you would never guess what the pointer points to, because only std::vector will be holding an array.
In the following code, im trying to build 2 arrays. The first one is an array given by the user, the second one is an array which has been sorted among other things, although kept short since the actual implementation is not nescessary :
int main()
{
int size = 0;
cout << "Please enter size: ";
cin >> size;
int array[size];
int newArray[size] = doSomething(array,&size);
return 0;
}
int* doSomething(int array[],int *size)
{
*size+=1;
int newArray[size];
//do something with the array and store it in the newArray
return newArray;
}
So my question is this:
My teacher told me that most compilers work differently, and the order of some operations might differ among them.
At the line int newArray[size] = doSomething(array,&size); I am expecting the size variable to be changed inside doSomething before it is used to initialize newArray. Once the doSomething method is finished running, it should return an array (WHICH I ASSUME It IS JUST RETURNING THE ADRESS OF THE FIRST ELEMENT OF THE ARRAY, PLEASE CORRECT ME IF THIS IS WRONG). Once it returns I want to store that address into my newly array, where the variable size is used to initalize the array's size. This variable should be according to my logic, equal to the original size entered by the user +1. So if the user enters a size of 4, the size of newArray should be 5. Is this a good way of going about it, or would it produce unreliable results for different compilers?
For the purpose of this exercise, I can only use built in array and pointers. So I cannot use vectors. Furthermore, in this example, the newArray is one element larger, but the actual code has a size which is dynamic, and therefore might be different each time. I can therefore not hard code the +1 inside the declaration.
If this is wrong, can someone point me in the right direction and help me to find a way where I can pass a built in array (no vectors or array<>), modify the contents and size of it and then return that array and store it in a variable in the caller method?
Thank you very much
First, standard C++ does not allow so-called variable-length arrays (VLAs); the size of the array in the declaration must be a compile-time constant. Standard C does allow them and both gcc and clang implement them as an extension. So technically, your code is ill-formed C++.
Let's accept the extension, for argument's sake. Now we have another problem, which is that arrays cannot be used as initializers for arrays. (An array could be used to initialize a pointer because the array will decay to a pointer in that context, but the pointer doesn't have a size at all. If you did tgat, though, you would introduce a different problem: the returned array has automatic storage duration which means that it is destructed and deallocated immediately. It is, therefore, a "dangling pointer" and using it is undefined behaviour.) You could work around that restriction a bit awkwardly by wrapping the array in a struct.
None of that touches the order of evaluation issue you are curious about. The answer is that the order is unspecified; the compiler might evaluate the function call before or after allocating space for the array. So even if your compiler allows VLAs, the size of this one is unspecified.
You have a problem here:
cin >> size;
int array[size];
Unless you use new you can't do that. The compiler creates the array container before the program runs, so you can't give it a custom size once it is running.
You must allocate your array as a new object on the heap:
cin >> size;
int* array = new int[size];
Maybe this will point you in the right direction, but I have no idea exactly what classes you are trying to call as you haven't included all of your source code.
I edited my previous answer, because I believe you are trying to simply call an array of ints, not a class called "array". If you just want a C-style array of integers, the above example is how you do it properly.
Keep in mind once you are done using the data you should call
delete[] array;
I want to know whether a pointer is pointing to an array or single integer. I have a function which takes two pointer (int and char) as input and tell whether a pointer is pointing to an array or single integer.
pointer=pointer+4;
pointer1=pointer1+4;
Is this a good idea?
Like others have said here, C doesn't know what a pointer is pointing to. However if you should choose to go down this path, you could put a sentinel value in the integer or first position in the array to indicate what it is...
#define ARRAY_SENTINEL -1
int x = 0;
int x_array[3] = {ARRAY_SENTINEL, 7, 11};
pointer = &x_array[0];
if (*pointer == ARRAY_SENTINEL)
{
// do some crazy stuff
}
pointer = &x;
if (*pointer != ARRAY_SENTINEL)
{
// do some more crazy stuff
}
That's not a good idea. Using just raw pointers there's no way to know if they point to an array or a single value.
A pointer that is being used as an array and a pointer to a single values are identical - they're both just a memory address - so theres no information to use to distinguish between them. If you post what you want to ultimately do there might be a solution that doesn't rely on comparing pointers to arrays and single values.
Actually pointers point to a piece of memory, not integers or arrays. It is not possible to distinguish if an integer is single variable or the integer is an element of array, both will look exactly the same in memory.
Can you use some C++ data structures, std::vector for example?
For C++ questions, the answer is simple. Do not use C-style dynamic arrays in C++. Whenever you need a C-style dynamic array, you should use std::vector.
This way you would never guess what the pointer points to, because only std::vector will be holding an array.
When a multidimensional array is passed to a function, why does C++ require all but the first dimension to be specified in parameter li
A better way to ask this is to ask why C++ doesn't require the first dimension to be specified.
The reason is that for all arrays, you can't pass arrays by value to a function. If you try to declare a function taking an array the compiler will adjust the declaration to the corresponding pointer type.
This means that it doesn't matter what dimension you specify as the dimension doesn't form part of the function signature.
For example, these all declare exactly the same function.
void f(int *p);
void f(int p[]);
void f(int p[10]);
void f(int p[100]);
When navigating the array pointed to by p in the function, the only information that the copmiler needs is the size of the array elements, i.e. sizeof(int) in this case.
For more complex arrays exactly the same holds. These are all the same:
void g(Type p[][10][20]);
void g(Type (*p)[10][20]);
void g(Type p[10][10][20]);
void g(Type p[99][10][20]);
But these are all different from:
void g(Type p[][5][20]);
because adjusting the dimension of anything other than the outer array dimension affects the size of (at least) the outer array's elements meaning that the pointer arithmetic for navigating the array would have to change.
For example int a[n][m] is an array whose type is an int array of length m. In other words, the length of array is part of its type. And as for all function parameters, compiler need to know its type.
There is no such thing as multidimensional array in c++. It is just a syntax which looks like it. In int a[4] and int b[5] a and b are different types.
If you refer to static allocation, this is simple.
Because the blocks of memory are contiguous which means that the memory cells are one after each other and the compiler knows where the next cell is in memory.
For unidimensional array in memory looks like this:
http://cplusplus.com/doc/tutorial/arrays/arrays3.gif
For bidimensional array in memory looks like this:
http://i.msdn.microsoft.com/dynimg/IC506192.png
In short: The compiler doesn't need the dimension, because a array decays to a pointer. But any additional dimension is needed by the compiler, to calculate the correct location in memory.
At first you need to know that an array in C/C++ is a linear continuous object in memory. Which is very efficient.
Because an array in C/C++ is a linear continuous object in memory, an array will decay to a pointer. Copying the complete array will be a waste of time and memory and is not requiered. A pointer is anything needed to go through the array. To go through the array you can take the increment-operator or any calculation which evaluates to a valid address in the array. You can set a delimiter in the array itself i.e. '\0' in a String, or pass the length to the function seperatley to tell your code where the end of the array is.
With multi-dimensional arrays the thing is a little bit more complicated. A multi-dimesional array is still only a linear continuous object in the memory! But the compiler needs the information about the additional dimensions to calculate to correct position in memory, imagine the following:
char array[10][10]; // 0 - 99
correct:
// formal argument tells your compiler, that each column is 10 elements long
funca(int array[10][10]) {
// access to element 25 (2 * 10 + 4, the 10 is known through your formal argument, remember that an array is null based)
array[2][3] = 'x';
}
wrong:
// formal argument tells your compiler, that ech colum is 5 elements long
funcb(int array[10][5]) {
// access to element 15 (2 * 5 * + 4, the 5 is known through your formal argument, remember that an array is null based)
array[2][3] = 'x';
}
A note (or warning):
Arrays in Java, especiallay (irregular) multi-dimensional arrays are completely different.
This question already has answers here:
How do I use arrays in C++?
(5 answers)
Closed 8 years ago.
In C# I use the Length property embedded to the array I'd like to get the size of.
How to do that in C++?
It really depends what you mean by "array". Arrays in C++ will have a size (meaning the "raw" byte-size now) that equals to N times the size of one item. By that one can easily get the number of items using the sizeof operator. But this requires that you still have access to the type of that array. Once you pass it to functions, it will be converted to pointers, and then you are lost. No size can be determined anymore. You will have to construct some other way that relies on the value of the elements to calculate the size.
Here are some examples:
int a[5];
size_t size = (sizeof a / sizeof a[0]); // size == 5
int *pa = a;
If we now lose the name "a" (and therefor its type), for example by passing "pa" to a function where that function only then has the value of that pointer, then we are out of luck. We then cannot receive the size anymore. We would need to pass the size along with the pointer to that function.
The same restrictions apply when we get an array by using new. It returns a pointer pointing to that array's elements, and thus the size will be lost.
int *p = new int[5];
// can't get the size of the array p points to.
delete[] p;
It can't return a pointer that has the type of the array incorporated, because the size of the array created with new can be calculated at runtime. But types in C++ must be set at compile-time. Thus, new erases that array part, and returns a pointer to the elements instead. Note that you don't need to mess with new in C++. You can use the std::vector template, as recommended by another answer.
Arrays in C/C++ do not store their lengths in memory, so it is impossible to find their size purely given a pointer to an array. Any code using arrays in those languages relies on a constant known size, or a separate variable being passed around that specifies their size.
A common solution to this, if it does present a problem, is to use the std::vector class from the standard library, which is much closer to a managed (C#) array, i.e. stores its length and additionally has a few useful member functions (for searching and manipulation).
Using std::vector, you can simply call vector.size() to get its size/length.
To count the number of elements in a static array, you can create a template function:
template < typename T, size_t N >
size_t countof( T const (&array)[ N ] )
{
return N;
}
For standard containers such as std::vector, the size() function is used. This pattern is also used with boost arrays, which are fixed size arrays and claim no worse performance to static arrays. The code you have in a comment above should be:
for ( std::vector::size_type i(0); i < entries.size(); ++i )
( assuming the size changes in the loop, otherwise hoist it, ) rather than treating size as a member variable.
In C/C++, arrays are simply pointers to the first element in the array, so there is no way to keep track of the size or # of elements. You will have to pass an integer indicating the size of the array if you need to use it.
Strings may have their length determined, assuming they are null terminated, by using the strlen() function, but that simply counts until the \0 character.
Als Nolrodin pointed out above, it is pretty much impossible to get the size of an plain array in C++ if you only have a pointer to its first element. However if you have a fixed-size array there is a well-known C trick to work out the number of elements in the array at compile time, namely by doing:
GrmblFx loadsOfElements[1027];
GrmblFx_length = sizeof(loadsOfElements)/sizeof(GrmblFx);