global variables and mulidimensional arrays outside of main in c++ - c++

EDIT #1
So I think my solution is to pass the class around through the functions, si then I have to get the size values in main and pass them into the class. So how would I create a multidimensional array within the class based on 2 int values? This is what I have, but I get the error "`ii' cannot appear in a constant-expression "
class tempHolder{
public:
bool C1[col1][row1];
tempHolder(){
}
tempHolder(int i, int ii){
int* C1 = new bool[i][ii];
}
}
So my program has a multidimensional array, but I'm using global variables (which I know is bad style) to declare the size of the array. The problem is that I also pass this array to functions and I use it in a class, like the code below...
#include <iostream>
using namespace std;
const int row1 = 12;
const int col1 = 32;
class tempHolder{
public:
bool C1[col1][row1];
void operator=(bool C2[col1][row1]){
for(int i=0;i<row1;i++)
for(int ii=0;ii<col1;ii++)
C1[i][ii] = C2[i][ii];
}
};
void printTable(bool CC[][row1], int, bool);
int main(int argc, char *argv[]) {
col1=5; //error
bool C1[col1][row1];
So I want to be able to change the values of row1 and col1 right at the beginning of main, which would then change the array size for the entire program. If I declare the global variables like above, then the program compiles, but since they are constants, I won't be able to change them. I can't use a #define because those are not changeable at all. So what can I do to resize the array for the entire program?

You cannot simply change the size of the array by simply changing the dimensions at runtime - you need to allocate the memory dynamically with new. Best is usually to use the STL containers - they have their length property built in and can be easily resized.

The size of the arrays is set before main begins, when the program is compiled.
So, even if col1 only changes once at startup, it still must be a proper non-const variable.
You likely want std::vector to implement a variable-sized array. Note that vector<bool> is a specially-optimized class which uses one bit, not one byte, per Boolean value. You might try using vector<char> instead if there are problems or performance is poor.
#include <iostream>
using namespace std;
int row1 = 12;
int col1 = 32;
typedef vector< vector< bool > > bit_array_2d;
class tempHolder{
public:
bit_array_2d C1;
void operator=( bit_array_2d const &C2 ){
C1 = C2;
}
};
int main(int argc, char *argv[]) {
col1=5; // OK
bit_array_2d C1( col1, vector< bool >( row1 ) );
A more advanced approach, if there are only a few potential sizes to select from, is to use template-parameterized C arrays.

Related

How to define array size in a struct from an "external" int defined in input

I have a struct with an array in it. The size of this array needs to be 3*input_variable. How can I define a number externally, which is multiplied by an input value, that I can use in a struct to declare the length of an array?
I have tried defining the variable h outside of main as
extern h
then assigning it's value in main from the input variable.
I have also tried to use (in summary)
nt main(int argc, char** argv)
{
int input_variable;
std::cin << input_variable;
int h = input_variable * 3;
void some_function(); // function does some stuff
// with the structs
#ifndef ARRAY_SIZING
#define ARRAY_SIZING h
#endif
return 0;
}
struct _struct_
{
constexpr std::size_t b = ARRAY_SIZING;
double* arr[b];
};
int some_function()
{
// structs are used down here.
return 0;
}
I would love to be able to allocate the size of an array in a struct using an input parameter. Thank you.
Hm. Plain C-arrays in C++. Mostly never needed. OK, you want to interface to a library function.
My guess is that the library does not expect an array, but a pointer. And since your struct contains an array to pointer to doubles, I assume the lib wants to see a double**.
I hardly can imagine that old libraries use references or pointer to arrays, something like:
void function (double* (&array)[10]); // Reference to array
void function (double* (*array)[10]); // Pointer to array
because also here you need an array with a size known at compile time.
I'd rather expect something like
void function (double** array, size_t size); // Pointer to Pointer to double
So, use a std::vector like this:
std::vector<double *> arr(input_variable * 3);
And if you want to hand over the arrays data to the lib functions, then use the vectors data function.
function (arr.data());
You could also create the array with new.
Last hint: Do not use raw pointers.
I hope that I could help a little . . .

function that returns an array of objects

I have got a structure
class pyatno {
int pyatnoNumber;
int locX, locY;
bool possible;
char *number;
char pyatnoView[4][4];
}
the idea is to make a function, that would return an array of pyatno.pyatnoView objects, but there is a mess. I don't understand how exactly I can get access to this "property". I am not strong in c++, so if it isn't real, or i am talking something wrong, explain please, cause I am really stacked in this question.
As you mentioned that you are not very strong with c++, and your question is rather unclear, here are several suggestions.
To get access to a class's attributes, c++ has the notion of visibility; The default visibility is private, that is, attributes and functions will not be visible outside of the class:
class Foo {
int some_value;
};
There are several ways you can retrieve data from an object, however to put it simply, you should either make the attribute public:
class Foo {
public:
int some_value;
};
or expose it via accessors/mutators:
class Foo {
int some_value;
public:
int get_some_value() { return some_value; }
void set_some_value(int v) { some_value = v; }
};
Another thing to note is that you can not return arrays! In c++, when an array passes a function boundary (that is to say, passed as a parameter to, or returned from), and in a lot of other cases, an array will 'decay' in to a pointer. For example, the following is how I would pass an array of characters (otherwise known as a c-string) to a function:
#include <iostream>
using namespace std;
void print_cstr(const char *cstr) {
cout << cstr << endl;
}
int main() {
const char my_cstr[20] = "foo bar baz qux";
print_cstr(my_cstr);
return 0;
}
So what happens for N-dimensional arrays? Well, if char[1] decays to char*, then char[1][1] will decay to char**, and so on. You might have noticed this with the older main signature in C programs, which is used to pass an array of strings representing arguments passed to the program:
int main(int argc, char **argv) { ... }
It is very important that you realise that this really is no longer an array. C style strings are a bit special, in that they are conventionally terminated with a null byte \0, which means that you can usually tell where the end of the string is, or how long it is. However, you no longer have any information on how long the array is! For example, this is completely legal:
#include <iostream>
using namespace std;
void bad_fn(const int *nums) {
for (unsigned i = 0; i < 20; ++i) {
cout << "num " << i << " = " << nums[i] << endl;
}
}
int main() {
const int my_nums[5] = { 1, 2, 3, 4, 5, };
bad_fn(my_nums);
return 0;
}
Your function will end up reading memory beyond the bounds of the array, as it has no way of knowing where the array begins or ends (after all, array indexes are just pointer arithmetic). If you do not want to have to worry about keeping track of, and passing around the length of your array (and I would suggest that you do not!), please look at using one of the C++ standard library's containers. std::vector and std::array are two examples that would fit in the use case you have provided, and you can find decent documentation for them here.

Setting class level 2D Array variable to passed in value - C++

I'm attempting to make a maze-solving program, and while the algorithm is sound (at least in my head), I've been running into a roadblock with 2D arrays. I'm coming from C# and Java, so the syntax is giving me grief.
Here's an SSCCE:
//Main.cpp
#include "MazeSolver.h"
int main()
{
MazeSolver mazeSolver;
char maze[51][51] = { }; // Not bothering to show code for populating the array
mazeSolver.setMaze(maze);
}
//MazeSolver.cpp
#include "MazeSolver.h"
MazeSolver::MazeSolver() { }
void MazeSolver::setMaze(char maze[51][51])
{
this->maze = maze;
}
//MazeSolver.h
#ifndef _MAZESOLVER_H
#define _MAZESOLVER_H
class MazeSolver
{
private:
char **maze; // This is likely the problem, I'm at wits end in regards to
// what notation is needed here. I do not want to hard-copy
// the entire array, I just need to access it (via pointer)
// I've also tried just using char maze[51][51] here, char *maze, etc...
public:
MazeSolver();
void setMaze(char maze[51][51]);
}
You cant assign (Or convert) 2d arrays (array[ROWS][COLUMNS]) to pointers to pointers (aka **) because the memory layout of a 2d array is (could be) very different to the memory layout the pointer of pointers could point to.
Check this thread for more info about this topic.
If suggest you to use the de facto C++ standard container, std::vector, instead of a plain array:
class MazeSolver
{
std::vector<std::vector<char>> maze;
void setMaze( const std::vector<std::vector<char>>& new_maze )
{
maze = new_maze;
}
};
Note that a vector has size 0 by default (At the point of its initialization), so you should fill it with elements:
for( std::size_t i = 0 i < ROWS ; ++i )
{
maze.push_back( std::vector<char>() );
for( std::size_t j = 0 ; j < COLUMNS ; ++j )
maze[i].push_back( ' ' );
}
However, C++11 (The current iteration of the language) has a std::array container which is like a C array but with the interface of other Standard Library Containers:
std::array<char,ROWS*COLUMNS> maze;
<rant>
This is one of the weird quirks of C++.
C++ 2D arrays are NOT jagged arrays. When you declare char maze[51][51], it actually allocates 1 contiguous array 51*51 members long. sizeof(maze) == 51*51. When you dereference a value, maze[a][b], what it actually does is *(maze+51*a+b). All this is under the hood.
A Jagged Array is an array of arrays, a char**. In this case, you have an array of 51 pointers size == (51*sizeof(void*)). In each position, the pointer points to a completely different memory location, allocated to 51 members long.
This is ANNOYING because you can't just convert the two, even by casting. You have to deal with weird syntax, such as char (*maze)[51] to get a pointer to the 2D array.
Whats even more annoying is the following happens:
int foo(int maze[51][51])
{
return sizeof(maze);
}
int maze[51][51];
int main(int argc, char** argv)
{
std::cout << sizeof(maze) << std::endl;//return 51*51*sizeof(int);
std::cout << foo(maze) << std::endl;//return 8, sizeof(void*);
}
So it implicitly passes by reference, not by value, which is opposite all the rest of C++.
</rant>
tl;dr;
The correct syntax for a pointer to a 2D array is char (*maze)[51];. Your syntax is for a jagged array (arrays of arrays) which is NOT the same thing in C++.

Pointer to array of character arrays

Okay, this one has me stumped. I am trying to pass an array of character arrays into my class's constructor. The class has a private attribute which stores a pointer to the array of character arrays. The class may then process the array via the pointer.
Below is some code that demonstrates the desired functionality. But, it won't compile. How do I fix this code so it works?
using namespace std;
const int MAX_LINES = 10, MAX_STRING = 80;
class Alphabetizer{
public:
Alphabetizer(char * inArray[][MAX_STRING]) : input(inArray){};
private:
char * input[MAX_LINES][MAX_STRING];
};
int main(){
char charArray[MAX_LINES][MAX_STRING];
Alphabetizer theAlaphBet(charArray);
return 0;
}
If you're insisting on using C-compatible character pointers, I think you'll have the best luck using a char ** as the type for input. This is more of the usual way to do this (in C at least), and it has the added benefit of not forcing you to define a maximum string size.
As others have pointed out, you can take advantage of std::string instead, which may be a better choice overall.
I'm guessing it's that you're not passing a pointer to char[][], you're passing a char[][].
Also, you should be using std::string instead of char arrays.
std::string will be the most appropriate here! It handles strings and character arrays well enough!
There are few errors in the code. I suppose you are trying to refer to the charArray in the main function from inside the Alphabetizer object. If that is the case the declaration
char * input[MAX_LINES][MAX_STRING];
is wrong because the above declaration makes input an array of MAX_LINE of ( array of MAX_STRING of (char*)). In summary input is an array not a pointer to array of whatever. If you had intended it to be a pointer - which is what rest of your code hints to me - then you have to do the following,
const int MAX_LINES = 10, MAX_STRING = 80;
class Alphabetizer{
public:
Alphabetizer(char ((*ar)[MAX_LINES])[MAX_STRING]) : m_ar(ar){};
private:
char ((*m_ar)[10])[80];
};
int main(){
char charArray[MAX_LINES][MAX_STRING];
char ((*ar)[MAX_LINES])[MAX_STRING] = &charArray;
Alphabetizer theAlaphBet(&charArray);
return 0;
}
Moreover doing,
input(inArray)
is wrong, as it is equivalent to doing the following,
char a[1] = {'a'};
char b[1] = {'p'};
a = b;
assigning an array to another does not copy one over another. You have to do explicit memcpy. (This semantics is not meaningful in c or c++)
It's difficult to tell without seeing the compile errors, but I think the problem might be this line:
Alphabetizer theAlaphBet(charArray);
You are passing the array directly rather than it's address. It should read:
Alphabetizer theAlaphBet( &charArray );
However I think you may be overcomplicating things. You might be better off using a reference rather than a pointer:
const int MAX_LINES = 10, MAX_STRING = 80;
class Alphabetizer{
public:
Alphabetizer(char & inArray[][MAX_STRING]) : input(inArray){};
private:
char & input[MAX_LINES][MAX_STRING];
};
int main(){
char charArray[MAX_LINES][MAX_STRING];
Alphabetizer theAlaphBet(charArray);
return 0;
}
You might also want to look into using std::string instead as this may help to simplify your code.

change global variables in c++

Is there a way to define a global variable by user input?
Lets say I use
#include...
#define N 12
double array[N][N];
void main();...
But I would like the user to be able to choose what N is.
Do I have to have N as a local variable or is there a way around this(without macros)?
I've a pretty small program but with a lot of different variables that need the N value.
Alternatively,
is there a way I could send a group of variables into a function without having to explicitly write them out every time.
for example
myfunction(var1,var2,var3...)
and instead write something like
myfunction(Allvariables)
Thanks a lot for Your answers!
This is a great forum.
int* data;
int main()
{
int n;
// get n from the user.
data = new int[n];
// use data.
.
.
delete[] data;
}
or just forget pointers for ever and use vector!
std::vector<int> data;
data.push_back(55);
// just push_back data!
=======================================================================
EDIT ::
If you want to use Edouard A. way :)
#include <iostream>
#include <sstream>
#include <vector>
int main(int argc, char* argv[])
{
std::vector<double>::size_type dataSize = 0;
std::stringstream convertor(argv[1]);
{
if(argc > 1)
{
convertor >> dataSize;
if(convertor.fail() == true)
{
// do whatever you want here in case
// the user didn't input a number.
}
}
}
std::vector<double> data(dataSize);
// use the vector here.
return 0;
}
I prefere to use lexical_cast in this case, but I am not sure if you have Boost.
#include <iostream>
#include <vector>
#include <boost/lexical_cast.hpp>
int main(int argc, char* argv[])
{
typedef std::vector<double>::size_type vectorSize;
if(argc < 2)
{
// err! The user didn't input anything.
}
vectorSize dataSize = boost::lexical_cast<vectorSize>(argv[1]);
std::vector<double> data(dataSize);
// use the vector here.
return 0;
}
1/ Yes but you need dynamic memory allocation. The program parameters are passed as argc and argv to the main function
int main(int argc, char **argv)
argc is the number of parameters
argv is the array of null terminated strings representing these arguments
argv[0] is the program itself.
2/You can either use variadic function va_start & the like, or functions overriding, or group your data in a structure and pass that to the function
No, that can't be done this way. You need to use dynamic (runtime) memory allocation (new[]). To perform static (compile-time) memory allocation the compiler needs to know the memory block size at compile time.
I'm not really sure what you're trying to do with myFunction but it sounds like you want to look at either creating a struct or pass a std::vector
Make a class (or struct) AllVariables and pass that in.
You don't say whether you want N defined at run time or compile time. If you want it defined at compile time, you can define N as a compiler command line arguement.