I'm trying to do this:
for(int k=0; k<context.size(); k++)
{
cc_no_issue[k]=0;
}
Can someone tell me how I can do that globally? Whenever I try I get these errors:
expected unqualified-id before "for"
k does not define a type
k does not define a type
This will do:
long cc_no_issue[100]={0};
And this is the proper initialization.
Note: this will initialize all the contents to 0.
This sentence:
long cc_no_issue[100]={1,2};
will set cc_no_issue[0] to 1, cc_no_issue[1] to 2, and the rest to 0. You could see the link above for more information.
If you have a global array of a basic type,
int some_array[1000];
It will automatically be initialized to zero. You do not have to initialize it. If you do need to run initialization code, you can do a hack like the following (in C++):
struct my_array_initializer {
my_array_initializer() {
// Initialize the global array here
}
};
my_array_initializer dummy_variable;
If you are on GCC (or Clang), you can execute code before main with the constructor attribute:
__attribute__((constructor))
void initialize_array()
{
// Initialize the global array here
}
All global variables (variables at file scope) are by default initialized to zero since they have static storage duration (C99 6.7.8.10). So strictly speaking, you needn't initialize them to zero, the C standard guarantees that they are zero by default.
It is good programming practice to initialize them explicitly however, as mentioned in the answer by Ziyao Wei.
No, you can't have code outside of functions.
You can put it inside some function and call that from the start of main.
One way is to add a global function that:
Checks if the array is initialized
Initializes the array if it wasn't initialized
Returns the array
Example Code:
int* get_cc_no_issue()
{
if(!kIsMyArrayInitialized)
{
/* todo: somehow get "context" globally... */
for(int k = 0; k < context.size(); k++)
{
cc_no_issue[k] = 0;
}
kIsMyArrayInitialized = true;
}
return cc_no_issue;
}
This is most useful if you want non-zero initialization.
For zero-initialization, see this answer to another question:
Is global memory initialized in C++?
You can put the array in the constructor of a global object.
int cc_no_issue[256];
struct Init {
Init(int a, unsigned int size)
{
memset(a, 0, size);
}
};
Init arr(cc_no_issue, sizeof(cc_no_issue));
As #Bo Persson, do it in a function instead. But, there is already an algorithm that does it for you in C++. No need to write a hand written loop.
std::fill(cc_no_issue, cc_no_issue+context.size(); 0) ;
More info on std::fill
Response to your comment:
To increment every element, you can make use of std::for_each passing a function object as the third argument.
#include <iostream>
#include <algorithm>
using namespace std;
void incrementHelper( int& a ){
++a;
}
int main(){
int ar[] = { 1,2,3,4,5 };
for_each(ar, ar+5, incrementHelper );
for( int i=0; i<sizeof(ar)/sizeof(ar[0]); ++i ){
cout << ar[i] << endl;
}
return 0;
}
Ouput:
2
3
4
5
6
for_each(ar, ar+5, incrementHelper );
For each element in the array, the algorithm is going to call the function, incrementHelper. In C terminology,to say, it serves as a call back for each element in the array. Now the call back function, receives the passed element by reference. So, modifying the reference will modify the referrent also. See the online demo.
You need to decide on the language. The machanisms for this are different in C and C++. Basically C has no method of running code before your main function starts, so you cannot do complex initialisation of an array in C. In C++ you do have some options, one is to stop using a bare array (which is a C construct anyway) and instead wrap your array inside a class, and do the initialisation inside the class constructor.
CC cc_no_issue;
class CC
{
public:
CC()
{
// initialisation of array goes here
}
private:
int array[100];
};
Another way it to use a vector, and write a function to initialise the vector.
std::vector<int> cc_no_issue = init_vector();
std::vector<int> init_vector()
{
std::vector<int> tmp;
// initialisation of tmp goes here
return tmp;
}
Related
(I'm a student and this is my first time posting so go easy on me.)
I want to create a function that takes a 2D array as an argument and in that array, I'd like to have a variable that I want to modify later in the code. This is the closest thing to an example of what I want:
int size; //the variable I want to change later
void function(int[][size]);
int main(){
cin >> size;
int array[size][size]; //the array I'm using with the variable as a parameter
function(array)
}
void function(int array[][size]){
//Do thing....
}
The code above does give me an error (array bound is not an integer constant) so if I make the variable a constant it will compile as seen here:
const int size = 10;
void function(int[][size]);
int main(){
int array[size][size];
function(array)
}
void function(int array[][size]){
//Do thing....
}
This does compile like I said, but now I can't modify the variable and need to declare its value in the code beforehand. I assume that the variable needs to be global so that I can use it in the function, and with that said, I can't get pointers to work either most likely because it's a global variable and not a local one. Here's an example of something I tried, but got an error (invalid conversion from ‘const int*’ to ‘int*’):
const int size = 10;
void function(int[][size]);
int main(){
int *other = &size;
*other = 5;
}
Any help would be appreciated, thanks.
Plain ol' arrays aren't resizeable in C++. Even more frustrating, their size has to be a constant - you can't make the size a variable that gets set at runtime. Ever more frustrating, the size you put in an array that's a function parameter is a constraint, and it's not even enforced. It's just decor.
As it was hinted in the comments, std::vector<TYPE> is the go-to "resizeable array" in C++. You can create a vector like this:
#include <vector>
int main() {
std::vector<int> my_int_array;
}
And you can resize it like this:
int new_size = 42;
my_int_array.resize(new_size);
And you can pass it to a function by reference(see the &) so that changes to myint_array inside the function affect it outside the function.
void my_awesome_function(std::vector<int>& int_array);
my_awesome_function(my_int_array);
So let's say you have a 2D matrix, implemented as a vector of vectors:
std::vector<std::vector<int>> matrix = { { 1,2,3 }, { 4,5,6 } }
If you want to change the number of columns, you have to resize each row array:
int new_column_count = 10;
for (auto& row : matrix) {
row.resize(new_column_count );
}
You can pass around matrix by reference (e.g. std::vector<std::vector<int>>&) and resize it when you need to.
How am I supposed to pass static 2d array to function in cpp as an argument? I tried something like that:
void foo(int (&tab)[N][N]) {
// function body
}
int main() {
int n;
cin >> n;
int tab[n][n];
foo(tab); // doesn't work
return 0;
}
I get "no matching function error" when I try to call foo.
I need static arrays, because vectors are too slow for my needs. I would like to avoid declaring array with 10000 rows and columns, too. Moreover, I would want to use functions, because it will make my code readable. Is there any solution for this problem which will meet my expectations?
With cin >> n;int tab[n][n];, you declare a variable length array (i.e. an array which's dimensions are not compile-time-constants).
You have two problems here: First, they are not supported by standard C++, and second they are not compatible with fixed size array parameters you introduced.
If you declare your array with compile time known size, however, it will work:
#define N 10
void foo(int (&tab)[N][N]) {
cout << tab[1][1] << endl;
}
int main() {
int tab[N][N] = {};
tab[1][1]=15;
foo(tab);
return 0;
}
The classical C++ solution would involve using vectors of vectors. If it's not suitable (because you want more speed or more control over memory), you can define your own class for a square 2-D array.
One idea I used in my code is, implement it using an underlying 1-D vector, with accessor method returning a pointer.
struct My_2D_Array
{
explicit My_2D_Array(size_t n):
m_size(n),
m_data(n * n)
{
}
int* operator[](size_t i)
{
return m_data.data() + i * m_size;
}
size_t m_size;
std::vector<int> m_data;
};
This not only lacks all sanity checks, and also makes bound-checked access impossible (because the accessor returns a bare pointer), but will work as a quick-and-dirty solution.
Usage in your code:
int foo(My_2D_Array& matrix)
{
// example
return matrix[2][3] + matrix[3][2];
}
int main()
{
int n;
cin >> n;
My_2D_Array tab(n);
foo(tab);
return 0;
}
This idea is highly customizable - you can make the code for My_2D_Array as simple or as clever as you want. For example, if you still don't like usage of vector, even though it's 1-D, you can manage (allocate/deallocate) your memory separately, and store int*, instead of vector<int>, in My_2D_Array.
Just use a vector<> of vector<int>. No need for mucking around with non-standard arrays.
I have written the following code but it is showing the error
use of parameter outside function body before ‘]’ token
The code is
#include <iostream>
using namespace std;
int n=10;
void a(int s[n][n])
{
cout<<"1";
}
int main()
{
int s[n][n]={0};
a(s);
}
I am trying to pass a multidimensional array of variable size using global variable. I don't want to use vectors in this.
Firstly C++ doesn't have variable-length arrays, So Instead of int s[n][n]={0}; you should use
std::vector<std::vector<int>> s(10,std::vector<int>(10));
Secondly how to pas 2D array to a function,
void a(std::vector<int> **s,int rows, int cols){
cout<<"1";
/* stuff with 2D array */
}
You've already received answers which explain the why. I'm offering this only as a matter of completeness to C++. Personally, though I don't understand why you're avoiding vectors, they do offer a more intuitive or pleasing solution. Inside of your function for handling the vectors, you can always consult std::vector<>.size() to ensure you stay within bounds or std::vector<>.at() and catch the exception that is thrown when accessing out of bounds. Nevertheless, your particular question may also be solved by templates. Below is your code, slightly modified, with comments to illustrate. I tested using gcc 4.8.5:
#include <iostream>
using namespace std;
// Made constant so that the compiler will not complain
// that a non-constant value, at compile time, is being
// used to specify array size.
const int n=10;
// Function template. Please note, however, this template
// will only auto-gen functions for 2D arrays.
template<int lb>
void a(int s[][lb])
{
// output the last element to know we're doing this correctly
// also note that the use of 9 hard-codes this function template
// to 2D arrays where the first dimension is always, at least, 10
// elements long!!!!!!
cout << s[9][lb - 1] << endl;
}
int main()
{
int s[n][1];
s[9][0] = 15;
a<1>(s); // explicitly call template with the size of the last dimension
a(s); // Call the same function generated from the previous call
int t[n][2];
t[9][1] = 17;
a(t); // compiler implicitly determines the type of function to generate
}
You can't. Your function a() needs to know the last dimension, which is the length of each row in the matrix. You need to pass this as an extra parameter to your function.
void a(int * matrix, int rows, int columns) {
int row = ...
int column = ...
if (row < rows && column < columns) {
cout << matrix[row*columns + column];
}
}
int main() {
...
a(&s[0][0], 10);
...
I have a multi-file program that reads data from a file and stores the values in various arrays. The size of the arrays is not known during the compiling. After the values are stored, I use another function to determine the maximum and minimum of each array and return the max/min. Before the "return maximum" statement, the values in the array are correct. After "return maximum", the values are changed or erased.
Here is some of the code including one of the 2D arrays and one of the 1D arrays (there are a few more of those but I removed them so there's less code for you to look at)
**EDITED:
FunctionValues.h: ** removed destructor block
class FunctionValues
{
//define variables, set up arrays of unknown size
public:
float **xvel;
int *imax;
int vessels;
int tot_gridpt;
public:
//Constructor -- initialization of an object performed here
FunctionValues(): xvel(NULL), imax(NULL) {}
//Destructor
~FunctionValues() {
}
void read_function(string filename);
};
FunctionValues.cpp: (this reads a file with some imax values, vessel numbers and velocities and stores them in the appropriate arrays, the other includes are also there) All the arrays made are stored in FunctionValues myval object
#include "FunctionValues.h"
using namespace std;
void FunctionValues::read_function(string filename)
{
std::ifstream myfile(filename.c_str());
//acquire variables
myfile >> vessels; //number of vessels
imax = new int[vessels];
//... code reading the file and storing them, then imax and some other values are multiplied to get int tot_gridpt
xvel = new float *[vessels];
for (int i = 0; i < vessels; i++)
{
xvel[i] = new float[tot_gridpt];
}
//arrays filled
for (int i = 0; i < limiter; i++)
{
myfile >> xvel[count][i];
}
}
Gridpts.cpp: ** range() arguments and parameters
#include "FunctionValues.h"
#include "Gridpts.h"
using namespace std;
// forward declarations
float range(float **velocities, const FunctionValues *myval, int num);
void Gridpts::create_grid(FunctionValues *myval, int ptsnum)
{
//find range, 1 for max, 0 for min from smooth wall simulation results rounded to the nearest integer
float maximum = range(myval->xvel, &myval, 1);
float minimum = range(myval->xvel, &myval, 0);
}
range.cpp: ** arguments changed to pass by pointer
float range(float **velocities, const FunctionValues *myval, int num)
{
if (num == 1)
{
float maximum = 0;
for (int round = 0; round < myval->vessels; round++)
{
for (int count = 0; count < myval->tot_gridpt; count++)
{
if (velocities[round][count] > maximum)
{
maximum = velocities[round][count];
}
}
}
maximum = ceil(maximum);
return maximum;
}
main.cpp:
corner_pts.create_grid(&myval, ptsnum);
This is where the error occurs. cout << "CHECKPOINT: " << myval.xvel[0][0] before "return maximum;" gives -0.39032 which is correct. After "return maximum", causes nothing to be printed and then the program crashes when trying run range() again using the xvel array. Similarly for myval.imax[0].
I apologize for copying in so much code. I tried to only include the essential to what is happening with the array. I have only started programming for about a month so I'm sure this is not the most efficient way to write code but I would greatly appreciate any insight as to why the arrays are being changed after returning a float. Thank you in advance for your time. (And if I have broken any rule about posting format, please let me know!)
So your program crashes when you call range() the second time. Therefore, your issue is most likely there.
Your program is crashing because you are taking your FunctionValues parameter by value, which is then destroyed at the end of the scope of the function, since it is local to the function.
// issue with myval being taken as a copy
float range(float **velocities, FunctionValues myval, int num)
{
//...
} // destructor for local function arguments are called, including myval's destructor
Explanation
Your function parameter FunctionValues myval is taken by copy. Since you have no copy constructor defined, this means that the default copy behavior is used. The default copy behavior simply copies the object data from the supplied argument at the call site.
For pointers, since they hold addresses, this means that you are copying the addresses of those pointers into an object local to the range() function.\
Since myval is local to the range() function, its destructor is called at the end of the scope of the function. You are left with dangling pointers; pointers holding the memory addresses of memory that you have already given back to the free store.
Simplified example of your error:
#include <iostream>
class X
{
public:
X() : p{ new int{ 0 } }
{
}
~X()
{
std::cout << "Deleting!" << std::endl; // A
delete p; // B
}
private:
int* p;
};
void func(X param_by_value) // C
{
// ...
}
int main()
{
X x; // D
func(x); // E
func(x); // F
}
You have variable x (D). You use it to call the function func() (E).
func() takes a parameter of type X by value, for which the variable name is param_by_value (C).
The data of x is copied onto param_by_value. Since param_by_value is local to func(), its destructor is called at the end of func().
Both x and param_by_value have an int* data member called p that holds the same address, because of 3..
When param_by_value's destructor is called, we call delete on param_by_value's p (B), but x's p still holds the address that was deleted.
You call func() again, this time the same steps are repeated. x is copied onto param_by_value. However, this time around, you try to use memory that has been given back to the free store (by calling delete on the address) and (luckily) get an error. Worse yet, when main() exits, it will attempt to call x's destructor again.
You need to do some research into function parameters in C++. Passing by value, passing by reference, passing by pointer, and all of those combined with const.
As user #MichaelBurr points out, you should also look up the rule of three (and rule of five).
I'm just wondering why you opted not to use functionality like std::max/min_element in and std::valarray/vector to allocate a contiguous chunk of memory?
Worse case scenario, if you're a fan of the explicit nature of 2d arrays x[a][b] you could create a basic matrix:
template <typename T>
class Matrix {
public:
Matrix(std::valarray<int>& dims) : dims(dims) {}
Matrix(std::valarray<int>& dims, std::valarray<T>& data) : dims(dims), data(data) {}
std::Matrix<T> Matrix::operator[](int i) {
auto newDims = std::valarray<int>(dims[1], dims.size() - 1);
auto stride = std::accumulate(std::begin(newDims), std::begin(newDims) + newDims.size(), 1, [](int a, int b){ return a * b; })
auto newData = std::valarray<T>(data[i * stride], data.size() - (i * stride));
return Matrix<T>(newDims, newData);
}
protected:
std::valarray<T> data;
std::valarray<int> dims;
}
I think more reliance on the standard libraries for their correctness will likely solve any memory access/integrity issues.
I was coding up a Union find data structure , and was trying to initialize the parent vector with a value parent[i]=i, Is there a way in c++ to initialize the vector like this , that is declaring a vector of size N , and not assigning fixed values to each element, rather position dependent value to each element. (without using any obvious for loops)
This is what I was looking for:
std::vector<int> parent(Initializer);
where Initializer is some class or a function.
To try out my hand a bit, I wrote this:
#include <iostream>
#include <vector>
using namespace std;
class Initializer {
private:
static int i;
public:
int operator() ()
{
return i++;
}
};
int main()
{
vector<int> parent(Initializer);
cout << parent[0];
return 0;
}
However I think I have messed up my concepts pretty bad here, and I am not getting what the declaration means, or what it is doing.
Please answer both the questions,
(1) How to initialize a vector with variable initial values.
(2) What exactly is the code I wrote doing?
This is a function declaration:
vector<int> parent(Initializer);
Becasue Initializer is a type name, you declared a function parent that takes Initializer as a (unnamed) parameter and returns vector<int>. See Most vexing parse.
To do what you want, you can do this:
std::vector<int> parent(N); // where N is the size you want
std::iota(parent.begin(), parent.end(), 0); // fill it with consecutive values
// starting with 0
There's std::generate algorithm that you can use to save result of a function (or function object) in a range:
std::generate(parent.begin(), parent.end(), Initializer());
Live demo.
There are several alternatives. If you want to initialize the vector with increasing values, then you can use std::iota.
std::vector<int> vec(size);
std::iota(std::begin(vec), std::end(vec), 0);
If you want something more general you could use std::generate.
std::vector<int> vec(size);
int n = 0;
std::generate(std::begin(vec), std::end(vec), [&n]() {return n++;});