I have something of this nature:
SomeClass {
public:
union {
int m_256[256];
int m_16[16][16];
int m_4[4][4][4][4];
}
SomeClass() {
// Initialize Array to some default value
for ( unsigned u = 0; u < 256; u++ ) {
m_256[u] = 0;
}
}
};
With the understanding of unions the for loop within the constructor will initialize m_256 to all 0s and the other 2 arrays are just another version or alias of it, so those arrays should be initialized as well since the memory size is exactly the same and the memory is shared.
I'd prefer not to go through a for loop to initialize all values of the array to some default value. Also since there are 3 arrays within this union, you can only have 1 non static member with an initialize list within a union. So this is valid.
union {
int m_256[256]{};
int m_16[16][16];
int m_4[4][4][4][4];
}
Instead of using the for loop within the constructor or typing the same number manually 256 times, is there a short hand method that will initialize all values within the array to the same initial value?
EDIT
Based on a comment from user657267 he said:
Keep in mind that technically you can't write to one union member and read from another
Consider this: without making any changes to the class above and simply adding this operator overload:
std::ostream& operator<<( std::ostream& out, const SomeClass& s ) {
out << std::endl;
out << "{Box, Slice, Row, Column}\n";
for (unsigned box = 0; box < 4; box++) {
for (unsigned slice = 0; slice < 4; slice++) {
for (unsigned row = 0; row < 4; row++) {
for (unsigned col = 0; col < 4; col++) {
out << "(" << box << "," << slice << "," << row << "," << col << ") = "
<< s.m_4[box][slice][row][col] << std::endl;
}
}
}
}
return out;
} // operator<<
Now in the main function we can do this.
int main() {
SomeClass s;
// Initialize This Array To Have Each Value Incremented From 0 - 255
for ( unsigned u = 0; u < 256; u++ ) {
s.m_256[u] = u;
}
// Print Out Our Array That Is In The Union Using The Overloaded Operator.
// Note The Overloaded Operator Is Using The declaration of m_p4 and not m_p256
std::cout << s << std::endl;
// Now We Know That If You Extract A Value From Any Given Index It Will Return That Value.
// So Lets Pull Out Two Random Values From Using The Other Two Members of the Union.
int A = s.m_4[0][2][1][3];
int B = s.m_16[12][9];
// Now Print Out A & B
std::cout << A << ", " << B << std::endl;
return 0;
}
Other than the printed array table the last two values are:
39, 201
Now if we scroll through the table and look for (0,2,1,3) the value is 39 and
to test out if 201 is correct; we used [12][9]. If you are using a double for loop to index a flat array the indexing is equal to (i * num_j + j ) so, knowing that the 2D Array Version of this 1D or 4D array is [16][16] in size we can calculate this value mathematically: 12 * 16 + 9 = 201.
Within my specific case doesn't this invalidate his statement? In c++ are unions not the sharing of memory between two variables, and if you have the same data type such as int & int doesn't this make them alias of one another? I was surely able to initialize the 1D flat array, use the 4D version to print a table, and was able to extract values from both the 2D & 4D versions.
Edit
I know what others are saying about you can't write to one and access another technically because of a case as such:
union foo {
int x;
char y;
};
Here is an excellent answer to a different question on unions Difference Between Structs & Unions. However, in my case here, the data type and the size in memory for all three arrays are the same. Also, if one value is changed in one I am expecting it to change in another. These are just different ways to access the same memory. Eventually this "nameless union" will be a private member within my class, and there will be public methods to retrieve a const reference to the full array, to retrieve the contents from the arrays by index values from each of the 3 types, and to place contents into the array by any of the three types.
All the boiler plate will be done behind the scenes in private. So I do not see this as in issue, and the behavior here is what I am after. It is not as if I'm creating an instance of a union where it is mixed types. I'm not doing bit fields with them. I'm basically conserving memory so I don't have to have 3 arrays that are 256 x (size of element) then have to have a bunch of copying from one array to another array semantics, this property of how unions work, is what I'm actually after. It is 1/3 the amount of memory used by a single instance of the class in use, probably 20% faster and more efficient without having to keep 3 different independent arrays synchronized every time an element is added or removed, or moved within the array.
As structs are defined: They will allocate enough memory for every data type and instance within the struct. You can set each data type independently
As unions are defined: They will allocate enough memory for the largest data type within the union. If you set one data type, it will change the other data type.
In the context of my class, the union is nameless so you can not create an instance of it, however you can access any of its members. In the case here with these three arrays:
byte a[256]; // 256 bytes
byte b[16][16]; // 16 x 16 = 256 bytes
byte c[4][4][4][4]; // 4^4 = 256 bytes
They are exactly the same size; and in my all three of these are the same array in my class. This is used to access the data in different ways.
The loop is certainly an overkill:
std::fill(std::begin(m_256), std::end(m_256), 42); // fills with 42
Other than that, no built-in language construct; it'd amount to pretty much the same as the above, though.
Related
#include<iomanip>
using namespace std;
void displaySeats(bool taken[][]){
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 30;j++)
if (taken[i][j])
cout << '*';
else
cout << '#';
cout << '\n';
}
}
int main()
{
bool taken[15][30];
int rows, clm;
rows = 15;
clm = 30;
displaySeats(taken);
system("PAUSE");
}
it is giving me errors like
an array may not have elements of this type line 6
'void displaySeats(bool [][])': cannot convert argument 1 from 'bool [15][30]' to 'bool [][]' line 25
'taken': missing subscript line 6
but if i move the code from the function to the main it works perfectly fine.
I can have a array of type bool.
there is subscript.
i've tried passing through a pointer to the array (which arrays are anyway)
i've tried passing through an array of pointers
a 2d array of pointers
a pointer of an array of pointers.
scoured stack exchange and looks at other peoples code and i am doing it almost line for line.
does it not work with bools? because it doesn't work with ints either.
When expecting an array argument on a function you don't need to know how many elements it has, since you can index it freely. However, you need to know how big each element is, to know how many bytes to skip for each index, when indexing.
In this case your element is a bool[30] with size 30 bytes. You need to signify this on your function signature.
void displaySeats(bool taken[15][30]){ // array 15*30 bool
// OR
void displaySeats(bool taken[][30]){ // array with elements bool[30]
// OR
void displaySeats(bool (*taken)[30]){ // pointer to element(s) bool[30]
See below on how 2d arrays are structured in memory and this will make sense.
This is a big topic. You need to research how arrays really work in C++. But the short (and surprising) answer is that you cannot have an array as a parameter to a function in C++. This code void func(int a[]) is actually an alternative for the pointer code void func(int* a).
But this simple rule only works for one dimension. With two dimensions only the first dimension is turned into a pointer. So the equivalent for your case would be
void displaySeats(bool (*taken)[30]){
or
void displaySeats(bool taken[][30]){
or
void displaySeats(bool taken[15][30]){
But the important part is that in all cases taken is a pointer not an array.
Because arrays are so useless in C++ we prefer to use std::vector, which doesn't have the same limitations (and has many other advantages besides).
The taken array must have some size defined like so taken[15][30].
Also, you have to include <iostream> in order to use cout.
try specifying size of array, or use reference see here
#include<iomanip>
#include <iostream>
using namespace std;
// template <typename t>
void displaySeats(bool taken[][30]){
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 30;j++)
if (taken[i][j])
cout << '*';
else
cout << '#';
cout << '\n';
}
}
int main()
{
bool taken[15][30];
int rows, clm;
rows = 15;
clm = 30;
displaySeats(taken);
system("PAUSE");
}
As mentioned, bool taken[][] isn't valid. Only the left-most (outer) array extent may be left unspecified.
I prefer the longest form to be explicit and to take the argument by reference. Motivation: Taking it as a pointer would lead to a runtime problem if you happen to pass in a nullptr by mistake (unless you check if(taken==nullptr) return; in the function). With a reference, you'd get a compilation error instead so there's no need to check if it's a nullptr.
Also, make the function argument const since you're not making changes to the array in the display function.
constexpr size_t ROWS = 15;
constexpr size_t COLS = 30;
void displaySeats(const bool (&taken)[ROWS][COLS]) {
using std::cout;
for (size_t i = 0; i < ROWS; i++) {
for (size_t j = 0; j < COLS;j++)
if (taken[i][j])
cout << '*';
else
cout << '#';
cout << '\n';
}
}
You can then easily turn this into a function template to accept arbitrary 2D arrays of bool:
template<size_t ROWS, size_t COLS>
void displaySeats(const bool (&taken)[ROWS][COLS]) {
// same as above
}
If you start to study language rules, not their interpretation, you'll come to realization that neither C nor C++ document doesn't mention an array with multiple dimensions at all, not like FORTRAN or flavors of Basic. It speaks about just an array as a form of object.
Array is an object which has a continuous storage containing multiple objects of same type. Array is an object. Thus we may have an array of arrays. That's what bool taken[15][30] is. It can be read this way
bool (taken[15])[30]; //Array of 15 arrays of 30 bools each
While this line is correct
void foo(bool arg[]) // same as void foo(bool *arg) for all purposes
And this one gives compiler some information:
void foo(bool arg[30]) // sizeof(arg) would return size of array,
// not size of pointer type
This line is ill-formed.
void boo(bool arg[][]) //
It would suggest an unknown type of array elements (how big is the element of array?), which contradicts ideology of strongly-typed language.
Two correct styles can be mixed:
void foo(bool arg[][30]) // same as void foo(bool (*arg)[30])
Here the parameter of function is a pointer to an array of bools.
Functions in C or C++ never could take an array or return an array. The reason to that is that C (and subsequently, C++) by default can pass parameters and return results by value, which means loading those values into stack. Doing that to array would be ineffective because of stack possible limitations. There were also logical conundrums in syntax, where name of array decays to a pointer. Thus arrays supposed to be passed by their address, by a pointer and can be returned only by pointer as well.
But you can pass structures by value and you can return them as result, even if they contain arrays. C++ classes expands functionality of original aggregate type struct and std::array is an example of template for such aggregate.
I have an Eigen matrix to be converted to a C array. I can replicate the issue with the following example.
#include <iostream>
#include <Eigen/Core>
int *test()
{
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
// just to check
arr(4)=3;
arr(5)=19;
return arr.data();
}
int main()
{
int *c_arr;
c_arr = test();
for (int i=0; i<6;++i)
{
std::cout << c_arr[i] << std::endl;
}
return 0;
}
Output:
0
0
1
1
3
19
Now if I print the converted C array values from within the test function the values are correct. However if I print the values from main (as shown above) the first two indices are always garbage. So I am wondering what is happening in the function call? I have tried this with different Eigen matrices (types, sizes) and I get the same result.
I'll start by saying I'm not 100% familiar with the Eigen library (just downloaded it to look at it out of curiosity) and it's documentation is a bit lacking but your problem is a fundamental C problem that can be remedied a few ways.
First we'll start by explaining what's happening in your code to give garbage values:
int *test()
{
/* create an auto scoped variable on the stack;
this variable is only "visible" to this function
and any references to it or it's underlying data
outside the scope of this function will result
in "undefined behaviour" */
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
arr(4)=3;
arr(5)=19;
/* arr.data() is defined as returning a pointer to the scalar underlying type (or
a C-style array in other words). Regardless of the type being returned, it is pointer based
and you are returning a pointer to a location in memory, not the actual data being held in
the memory. */
return arr.data();
} /* the variable arr is destroyed here since we left function scope and the return value (the pointer location)
is put in the return register and "program flow" is returned back to the main function where the pointer being
returned now points to "invalid" memory */
int main()
{
int *c_arr; // create a pointer type that can reference int types
c_arr = test(); // point it to the result of the test function (see notes above)
/* c_arr now points to a memory location returned from test, but since the
arr variable no longer exists here, when you go through and print the values pointed
to at those memory locations you will get what is at those locations and could be "anything"
except a valid reference to the original arr variable and it's underlying data. */
for (int i=0; i<6;++i)
{
std::cout << c_arr[i] << std::endl;
}
return 0;
}
So that's the why, as for how to fix it there are a couple of ways to go about your problem; one is to pass the return array in as a variable in to your test function (e.g. void test(int*& val)), you could then choose to allocate new memory to the variable in the test function, or assume the user has already done so, and must also assume the user will clean up after themselves and call delete[] (not just delete since you're operating on arrays of data).
But this has many caveats of needing to know how much space to allocate and being sure to deallocate when done. I'm not sure why you specifically need a C-style array but since you're using C++, it might be more prudent if you use some of the STL and container functions available to you to help you out, example:
#include <iostream>
#include <vector>
#include <Eigen/Core>
std::vector<int> test()
{
Eigen::MatrixXi arr = Eigen::MatrixXi::Ones(6,1);
arr(4)=3;
arr(5)=19;
// we need the size so we know how big of a container to allocate
std::size_t sz = arr.innerSize() * arr.outerSize();
std::vector<int> ret(sz);
// get a temporary C array pointer so we can reference the data
int* tmp = arr.data();
// copy from tmp[0] to tmp[sz] and insert the data into the first element of ret
std::copy(tmp, tmp+sz, ret.begin());
// return the (copied) data
return ret;
}
int main()
{
std::vector<int> c_arr = test();
// c_arr now points to valid data it holds and can be iterated on
for (std::size_t i = 0; i < c_arr.size(); ++i) {
std::cout << c_arr[i] << std::endl;
}
// if you need a C-style array from here, you can easily copy the data
// from the vector to your C-array
return 0;
}
I looked into using the cast() function of the class, but could not quite figure out the syntax to make it less painful than just copying it the above way since it looks like you'd have to call the cast function to a differnt Eigen type and then cast again from there, but know there is a cast function and other methods to get the underlying data of the MatrixX classes if you need access to it.
I hope that can help.
what would be the result if I wrote this
int array1[2];
cout << array1[0] ;
and how can I do this pseudocode :
if array1[0] doesn't have a value then assign its value to 1
I'm using C++ on DevCPP
The elements of array are uninitialized, and it is undefined behaviour to read them before writing to them. Your program is ill-formed. There is no way to "check" for this; it is your responsibility to write a correct program.
The initial value of unassigned array values is undefined (unless the array element type is a class/struct, in which case the default constructor will be called for each array element). In your first example, the behavior is undefined since you have not initialized the array element before using it.
If you want to retain an "unassigned" status then you need to use a class that encapsulates this, for example using the nullable pattern for value types.
Consider using Boost.Optional: you'd declare the array as boost::optional<int> array1[2]; and then you can test if (array1[0]) to see if that particular element has a value.
There is one point that the answers I'm seeing thus far seem to have missed. It depends on where your array is defined.
If the array is local to a function, like:
int f() {
int array1[2];
cout << array1[0] ;
}
...then the other answers are correct: the content of array1 contains unspecified values, and your attempt to read the value and send it to cout gives undefined behavior.
On the other hand, you may have defined array1 as a global variable:
int array1[2];
int f() {
cout << array1[0];
}
In this case, the content of array1 is required to be initialized to 0 for any arithmetic type (or NULL for an array of pointers). In a case like this, writing out the value in array1[0] is perfectly fine and gives defined results -- it must be 0. In this case, there is no any way to tell whether an element of an array containing the value 0 has that value because it was automatically initialized to 0, or was assigned that value later.
If you really need to know whether a value has been written to a variable, it's possible to write a class that will do that:
template <class T>
class value {
T val;
bool assigned;
public:
value(T const init=T()) : assigned(false), val(init) {}
value &operator=(T const &t) {
assigned = true;
val = t;
}
operator T() { return val; }
bool was_assigned() { return assigned; }
};
// ...
value<int> array2[2];
if (!array2[0].was_assigned())
array2[0] = 1;
It's usually easier and more efficient to just define the type to always start out initialized to a known value, so you never really care about whether it's been assigned to or not though. In short, although this supports what you've asked for, my immediate reaction is that there's probably a better/cleaner way to accomplish your ultimate goal. Before you even consider using something like this, I'd strongly recommend stepping back from what you're doing, and trying to figure out if there's a better way to do it. My guess is that there is/will be (and if you can't find it, you might want to ask another question, telling us about why you're trying to do this, to see if somebody can see a more direct way to accomplish your goal).
As far I remember that depend on the OS
As other users said, you need to initialize a then use a for loop to test each value one by one and modify them, if they fulfill a condition, I leave you a C snippet:
/* Variable declaration and initialization to 0s (You can use another value as default )*/
int a[ 5 ] = { 0 };
/* If the array[ i ] has 0 as value */
for( i = 0; i < 5; i++){
if ( a[ i ] == 0 ){
a[ i ] = 1;
}
}
If you don't initialise the element yourself, the element will obtain the value from the memory location it is stored on now (and will most probably convert it to its data type). Consider this program :
#include <iostream>
using namespace std;
int foo(int A[])
{
cout << A[0] << A[1];
}
int main()
{
int array[2];
foo(array);
}
This will give the output 00.
But now consider this code :
int main()
{
int array[2];
cout << array[0] << array[1];
}
It will give some random integer output. This is so because the uninitialised array picks up the value stored on the memory location it now occupies. You can check its memory adress by &array[0] and print it in different data types for some thought provoking questions.
eg: cout << &array[0] << char(array[0]) << bool(array[0]) etc.
In the following code, can the value of int be predicted ( how ? ), or it is just the garbage ?
union a
{
int i;
char ch[2];
};
a u;
u.ch[0] = 0;
u.ch[1] = 0;
cout<<u.i;
}
I would say that depends on the size of int and char. A union contains the memory of the largest variable. If int is 4 bytes and char[2] represents 2 bytes, the int consumes more memory than the char-array, so you are not initialising the full int-memory to 0 by setting all char-variables. It depends on your memory initialization mechanisms but basically the value of the int will appear to be random as the extra 2 bytes are filled with unspecified values.
Besides, filling one variable of a union and reading another is exactly what makes unions unsafe in my oppinion.
If you are sure that int is the largest datatype, you can initialize the whole union by writing
union a
{
int i;
char ch[2];
};
void foo()
{
a u = { 0 }; // Initializes the first field in the union
cout << u.i;
}
Therefore it may be a good idea to place the largest type at the beginning of the union. Althugh that doesn't garantuee that all datatypes can be considered zero or empty when all bits are set to 0.
//Prints out a given array
template <typename T>
void print(T t)
{
for(int i = 0; i < t.size(); i++)
{
cout << t[i] << " ";
}
cout << endl;
}
I have an idea but it includes passing the size of the array. Is it possible to avoid this?
*Update
Thanks for all of the answers/ideas but this problem is getting way deeper than my snorkeler can handle. I wanted to rewrite my C++ code in C because it was horribly written and slow. I see now that I have an opportunity to make it even worse in C. I'll rewrite it from the ground up in Python(performance be damned). Thanks again
If you don't have ELEMENTS, it's
#define ELEMENTS(a) (sizeof(a)/sizeof(*a))
Then,
#define print_array(a, specifier) print_array_impl(a, specifier, ELEMENTS(a), sizeof(*a))
void print_array_impl(void* a, char* specifier, size_t asize, size_t elsize)
{
for(int i = 0; i < asize; i++)
{
// corrected based on comment -- unfortunately, not as general
if (strcmp(specifier, "%d") == 0)
printf(specifier, ((int*)a)[i]);
// else if ... // check other specifiers
printf(" ");
}
printf("\n");
}
Use like this
print_array(a, "%d") // if a is a int[]
and, a needs to be an array name, not a pointer (or else ELEMENTS won't work)
You cannot know what is the size of an array without passing the size of that array (except operating with sizeof in static arrays). This is because the a pointer to a block of memory will only point to the base of the block of memory, from which you can know where the array/block of memory starts, but as there is no end defined you cannot determine where it will end.
You either need to set your own length per array and preserve it, and use it with the array like as described:
You can make a new type like:
struct _my_array {
typename arr[MAX];
int n;
} my_array;
OR
struct _my_array {
typename *arr;
int n;
} my_array;
In this case you need to allocate the a block of memory dynamically with new or malloc , and when finished free the memory with delete or free (respectively).
Or you can simply pass the array number of elements through the function.
Another way is to use a special terminator value of your array type which if encountered will be determined as the end of the array. In this case you need not preserve the size. For example a string is '\0' terminated, so all the string functions know that when a '\0' character is encounter in the char array it will consider that the string has end.
UPDATE
Because this is a generic function and the array can be of any type, one thing which you can do is like this:
struct _my_generic_arr {
void *arr;
int n;
int type;
} my_generic_arr;
When populating this array you can use any type. To identify which type, pass an identified in the type component. Each unique value will determine which type does the arr pointer actually points to (was actually the intended type to be pointed). The n will define the length. Now, depending on different values of type make a switch - case or an if - else ladder or nest, and process the array as you need.
It is impossible in c to track the size of an array in other block,,
It would be a better option to pass the size of the array along..
The other option would be to declare a global variable that has the size and using that variable inside the function
Eg,,
int size=<some value>
void main()
{
int arr[<same value>];
}
void print(T t)
{
for(int i = 0; i < size; i++)
{
printf("%d ",t[i]) //assuming T as int
}
printf("\n");
}
In C, you would need to pass two additional parameters: the size of the array (as you mentioned), and some way of indicating how to convert t[i] into a string. To convert t[i] to a string, you could create a custom switch statement to decode possible types, pass a pointer to a function that will return the string pointer, or you could pass the printf format specifier (e.g. "%d" for integer).
The problem is larger than you think. If you have an array of size 12, how do you know what data is held in that array? It could be 3 char*'s (on 32 bit system), 3 int32_t's, or even 12 chars. You have no way of knowing how to interpret the data. The best you could do is to implement your own version of a v-table and putting a print or toString function into it.
typedef struct {
void *array;
size_t length;
int element_width;
printer_t to_string;
} container;
printer_t is a type that describes a function pointer that takes an element pointer and returns a string (or prints it, if you don't want to free the string). This is almost never worth doing in C. That doesn't mean it can't be done. I would emphasize, though, that none of this is intended to imply that it should be done.
The function itself would look something like this:
void print(container *thing)
{
size_t offset;
int width;
char *stringified;
width = thing->element_width;
for (offset = 0; offset * width < thing->length; offset += width)
{
stringified = thing->to_string(thing->array + offset);
printf("%s ", stringified);
free(stringified);
}
}
What this does is essentially turn a struct into a faux class with a function pointer for a method. You could be more object-oriented and put the method in the type being printed and make it an array of those instead. Either way, it's not a good idea. C is for writing C. If you try to write in a different language, you'll end up with all sorts of terrible stuff like this.