I wish to initialize a multidimensional, dynamic array inside a class. But, I am getting an error.
I have seen several examples on the net. They seem to be difficult. I am new to coding. I would like a simple solution if possible.
class myp
{
int ntc = 5;
public:
double** y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new int[3];
};
int main()
{
int x;
myp mp;
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;;
return 0;
}
test.cpp:12:2: error: expected unqualified-id before ‘for’
for(int i = 0; i < ntc; i++)
^~~
test.cpp:12:17: error: ‘i’ does not name a type
for(int i = 0; i < ntc; i++)
^
test.cpp:12:26: error: ‘i’ does not name a type
for(int i = 0; i < ntc; i++)
You need to do class initialisation in the constructor function, and cleanup in the destructor.
class myp
{
int m_numColumns;
int m_numRows;
double** y;
public:
// overload array operators
double* operator [] (size_t row) { return y[row]; }
const double* operator [] (size_t row) const { return y[row]; }
// return dimensions of array
int numColumns() const { return m_numColumns; }
int numRows() const { return m_numRows; }
// constructor
myp(int nc, int nr) : m_numColumns(nc), m_numRows(nr)
{
y = new double*[m_numRows];
for(int i = 0; i < m_numColumns; ++i)
y[i] = new int[m_numColumns];
}
// destructor
~myp()
{
for(int i = 0; i < m_numColumns; ++i)
delete [] y[i];
delete [] y;
}
// be careful of the copy ctor. I'm deleting it in this case!
myp(const myp&) = delete;
// edit: as per user4581301's suggestion
myp() = delete;
myp(myp&&) = delete; // remove move ctor
myp& operator = (const myp&) = delete; // remove assignment
myp& operator = (myp&&) = delete; // remove move assignment
};
int main()
{
myp mp(5, 3);
mp[1][1] = 3;
cout << mp[1][1]<<endl;
return 0;
}
Just For Run.
class myp
{
int ntc = 5;
public:
double **y;
void initArray()
{
y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new double[3]; // i change this line [new int] to [new double]tv
}
};
int main()
{
int x;
myp mp;
mp.initArray();
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;;
return 0;
}
using constructor & destructor
class myp
{
int ntc = 5;
public:
double **y;
myp() // run at created
{
y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new double[3];
}
~myp() // run at the end of life cycle
{
/* free memory here */
}
};
int main()
{
int x;
myp mp; // myp() called
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;
return 0;
}
using constructor with parameter, for dynamic size
class myp
{
// int ntc = 5; // using at created
public:
double **y;
myp(int ntc, int size) // run at created
// if you want to use only myp mp;
// myp(int ntc = 5, int size = 3) {} will be helpful
{
y = new double*[ntc];
for(int i = 0; i < ntc; ++i)
y[i] = new double[size];
}
~myp() // run at the end of life cycle
{
/* free memory here */
}
};
int main()
{
int x;
myp mp(5, 3); // myp(int, int) called
mp.y[1][1] = 3;
cout<<mp.y[1][1]<<endl;
return 0;
}
Related
Assume I have a class A that has say 3 methods. So the first methods assigns some values to the first array and the rest of the methods in order modify what is computed by the previous method. Since I wanted to avoid designing the methods that return an array (pointer to local variable) I picked 3 data member and store the intermediate result in each of them. Please note that this simple code is used for illustration.
class A
{
public: // for now how the class members should be accessed isn't important
int * a, *b, *c;
A(int size)
{
a = new int [size];
b = new int [size];
c = new int [size];
}
void func_a()
{
int j = 1;
for int(i = 0; i < size; i++)
a[i] = j++; // assign different values
}
void func_b()
{
int k = 6;
for (int i = 0; i < size; i++)
b[i] = a[i] * (k++);
}
void func_c()
{
int p = 6;
for int (i = 0; i < size; i++)
c[i] = b[i] * (p++);
}
};
Clearly, if I have more methods I have to have more data members.
** I'd like to know how I can re-design the class (having methods that return some values and) at the same time, the class does not have the any of two issues (returning pointers and have many data member to store the intermediate values)
There are two possibilities. If you want each function to return a new array of values, you can write the following:
std::vector<int> func_a(std::vector<int> vec){
int j = 1;
for (auto& e : vec) {
e = j++;
}
return vec;
}
std::vector<int> func_b(std::vector<int> vec){
int j = 6;
for (auto& e : vec) {
e *= j++;
}
return vec;
}
std::vector<int> func_c(std::vector<int> vec){
//same as func_b
}
int main() {
std::vector<int> vec(10);
auto a=func_a(vec);
auto b=func_b(a);
auto c=func_c(b);
//or in one line
auto r = func_c(func_b(func_a(std::vector<int>(10))));
}
Or you can apply each function to the same vector:
void apply_func_a(std::vector<int>& vec){
int j = 1;
for (auto& e : vec) {
e = j++;
}
}
void apply_func_b(std::vector<int>& vec){
int j = 6;
for (auto& e : vec) {
e *= j++;
}
}
void apply_func_c(std::vector<int>& vec){
// same as apply_func_b
}
int main() {
std::vector<int> vec(10);
apply_func_a(vec);
apply_func_b(vec);
apply_func_c(vec);
}
I'm not a big fan of the third version (passing the input parameter as the output):
std::vector<int>& func_a(std::vector<int>& vec)
Most importantly, try to avoid C-style arrays and use std::vector or std::array, and don't use new, but std::make_unique and std::make_shared
I'm assuming you want to be able to modify a single array with no class-level attributes and without returning any pointers. Your above code can be modified to be a single function, but I've kept it as 3 to more closely match your code.
void func_a(int[] arr, int size){
for(int i = 0; i < size; i++)
arr[i] = i+1;
}
void func_b(int[] arr, int size){
int k = 6;
for(int i = 0; i < size; i++)
arr[i] *= (k+i);
}
//this function is exactly like func_b so it is really unnecessary
void func_c(int[] arr, int size){
int p = 6;
for(int i = 0; i < size; i++)
arr[i] *= (p+i);
}
But if you just want a single function:
void func(int[] arr, int size){
int j = 6;
for(int i = 0; i < size; i++)
arr[i] = (i+1) * (j+i) * (j+i);
}
This solution in other answers is better, if you are going to allocate memory then do it like this (and test it!) also if you are not using the default constructor and copy constructor then hide them, this will prevent calling them by accident
class A{
private:
A(const &A){}
A() {}//either define these or hide them as private
public:
int * a, *b, *c;
int size;
A(int sz) {
size = sz;
a = new int[size];
b = new int[size];
c = new int[size];
}
~A()
{
delete[]a;
delete[]b;
delete[]c;
}
//...
};
I have a class that looks like this:
class testy {
int *arr1, *arr2, *resu;
int n;
testy() {
n = 100000000;
arr1 = new int[n];
arr2 = new int[n];
resu = new int[n];
for (int i = 0; i < n; i++) {
arr1[i] = i;
arr2[i] = -i;
}
}
void worker(int Idx) {
resu[Idx] = arr1[Idx] + arr2[Idx];
}
void doTest() {
parallel_for(0, n, worker);
}
};
however I cant compile it since "testy::worker function call missing argument list"
the test worked fine while the worker wasn't a member of the class so I'm guessing I need to specify class instance here or something? How would I do that?
Array memory Allocation doesn't work
I saw the following code and found that it doesn't compile.
Is the code in the OP correct?
Thank you
class A {
};
class B : public A {
int num;
};
int main() {
/* Original Post
error: expected initializer before ‘*’ token
A vec*[5] = new B*[5];
A vec*[5] = new B*[5]; // <<< I don't understand this line
for(int i = 0; i < 5; i++)
{
vec[i] = new B();
}
*/
// My modified version
A* vec[5];
for(int i = 0; i < 5; i++)
{
vec[i] = new B();
}
return 0;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Operator[][] overload
I have made class which contains an array containing (in one row) all the numbers from the given 2d array. For example given: {{1,2}{3,4}} the b field in the object of class T contains {1,2,3,4}. I would like to overload[][] operator for this class so it will work like that
T* t.....new etc.
int val = (*t)[i][j]; //I get t->b[i*j + j] b is an 1dimension array
class T{
public:
int* b;
int m, n;
T(int** a, int m, int n){
b = new int[m*n];
this->m = m;
this->n = n;
int counter = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
b[counter] = a[i][j];
counter++;
}
}
}
int main()
{
int m = 3, n = 5, c = 0;
int** tab = new int*[m];
for(int i = 0; i < m; i++)
tab[i] = new int[n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
tab[i][j] = c;
c++;
cout<<tab[i][j]<<"\t";
}
cout<<"\n";
}
T* t = new T(tab,3,5);
};
You cannot. You have to overload operator[] to return a proxy object, that in turn, overloads operator[] to return the final value.
Something like:
class TRow
{
public:
TRow(T &t, int r)
:m_t(t), m_r(r)
{}
int operator[](int c)
{
return m_t.tab[m_t.n*m_r + c];
}
private:
T &m_t;
int m_r;
};
class T
{
friend class TRow;
/*...*/
public:
TRow operator[](int r)
{
return TRow(*this, r);
}
};
Instead of saving a T& in TRow you could save directly a pointer to the row, that's up to you.
A nice feature of this solution is that you can use the TRow for other things such as operator int*().
In the case of a 2d array, you don't need to create a proxy type. Just use int*:
#include <iostream>
class T {
public:
int m, n;
int *b;
T(int m, int n) : m(m), n(n), b(new int[m*n]) {
}
int*operator[](std::size_t i) {
return &b[i*m];
}
};
int main () {
T t(2,2);
t[0][0] = 1;
t[0][1] = 2;
t[1][0] = 3;
t[1][1] = 4;
std::cout << t.b[0] << t.b[1] << t.b[2] << t.b[3] << "\n";
}
I'm writing a genetic algorithm for which I'm creating a "crossover" operator as a class object that is passed the two parent "chromosomes" Because the input and therefore the output chromosomes are variable lengths, my idea was two divide the input chromosomes and place in a sort of storage class variable, then resize the input chromosomes, and then finally refill the input chromosomes. I'm getting a bad_alloc error, however. If someone could spot my error I'd very much appreciate the help.
Thanks! My class code is below. Note that "plan_vector" is a 2d vector of int types.
#include <iostream>
#include <vector>
#include <eo>
class wetland_vector : public std::vector<int> {
public:
wetland_vector() : std::vector<int>(1, 0) {
}
};
std::istream& operator>>(std::istream& is, wetland_vector& q) {
for (unsigned int i = 0, n = 1; i < q.size(); ++i) {
is >> q[i];
}
return is;
}
std::ostream& operator<<(std::ostream& os, const wetland_vector& q) {
os << q[0];
for (unsigned int i = 1, n = 1; i < q.size(); ++i) {
os << " " << q[i];
}
os << " ";
return os;
}
class wetland_vector_Init : public eoInit<wetland_vector> {
public:
void operator()(wetland_vector& q) {
for (unsigned int i = 0, n = q.size(); i < n; ++i) {
q[i] = rng.random(10);
}
}
};
class plan_vector : public eoVector<double, wetland_vector> {
};
int read_plan_vector(plan_vector _plan_vector) {
for (unsigned i = 0; i < _plan_vector.size(); i++) {
//Call function that reads Quad[1]
//Call function that reads Quad[2]
//etc
return 0;
}
return 0;
};
class eoMutate : public eoMonOp<plan_vector> {
int subbasin_id_min;
int subbasin_id_max;
int wetland_id_min;
int wetland_id_max;
bool operator() (plan_vector& _plan_vector) {
//decide which Quad to mutate
int mutate_quad_ID = rng.random(_plan_vector.size());
//decide which Gene in Quad to mutate
int mutate_gene_ID = rng.random(_plan_vector[mutate_quad_ID].size());
//mutation procedure if first slot in the Quad is selected for mutation
if (mutate_quad_ID = 0) {
_plan_vector[mutate_quad_ID][mutate_gene_ID] = rng.random(subbasin_id_max);
}
//mutation procedure if second slot in the Quad is selected for mutation
if (mutate_quad_ID = 1) {
_plan_vector[mutate_quad_ID][mutate_gene_ID] = rng.random(subbasin_id_max);
}
//note: you'll need to add more for additional wetland characteristics
return true;
};
public:
void set_bounds(int, int, int, int);
};
void eoMutate::set_bounds(int a, int b, int c, int d) {
subbasin_id_min = a;
subbasin_id_max = b;
wetland_id_min = c;
wetland_id_max = d;
}
double evaluate(const plan_vector& _plan_vector) {
int count = 0;
for (int i = 0; i < _plan_vector.size(); i++) {
for (int j = 0; j < _plan_vector[i].size(); j++) {
count += _plan_vector[i][j];
}
}
return (count);
}
class eoQuadCross : public eoQuadOp<plan_vector> {
public:
std::string className() const {
return "eoQuadCross";
}
plan_vector a1;
plan_vector a2;
plan_vector b1;
plan_vector b2;
bool operator() (plan_vector& a, plan_vector& b) {
int cross_position_a = rng.random(a.size() - 1);
int cross_position_b = rng.random(b.size() - 1);
for (int i = 0; i < cross_position_a; i++) {
a1.push_back(a[i]);
}
for (int i = cross_position_a; i < a.size(); i++) {
a2.push_back(a[i]);
}
for (int i = 0; i < cross_position_b; i++) {
b1.push_back(b[i]);
}
for (int i = cross_position_b; i < b.size(); i++) {
b2.push_back(b[i]);
}
int size_a = b2.size() + a1.size();
int size_b = a2.size() + b1.size();
a.resize(size_a);
b.resize(size_b);
for (int i = 0; i < b2.size(); i++) {
a.push_back(b2[i]);
}
for (int i = 0; i < a1.size(); i++) {
a.push_back(a1[i]);
}
for (int i = 0; i < a2.size(); i++) {
b.push_back(a2[i]);
}
for (int i = 0; i < b1.size(); i++) {
b.push_back(b1[i]);
};
//Return bool
return true;
}
};
int main() {
unsigned int vec_size_min = 1;
unsigned int vec_size_max = 10;
unsigned int pop_size = 100;
//BEGIN COPY PARAMETRES
const unsigned int MAX_GEN = 100;
const unsigned int MIN_GEN = 5;
const unsigned int STEADY_GEN = 50;
const float P_CROSS = 0.8;
const float P_MUT = 0.5;
const double EPSILON = 0.01;
double SIGMA = 0.3;
const double uniformMutRate = 0.5;
const double detMutRate = 0.5;
const double normalMutRate = 0.5;
//END COPY PARAMETERS
rng.reseed(1);
//Create population
wetland_vector_Init atom_init;
eoInitVariableLength<plan_vector> vec_init(vec_size_min, vec_size_max, atom_init);
eoPop<plan_vector> pop(pop_size, vec_init);
//Create variation operators
eoMutate mutate;
mutate.set_bounds(1, 453, 1, 4);
eoQuadCross crossover;
eoDetTournamentSelect<plan_vector> select(3);
eoSGATransform<plan_vector> transform(crossover, .5, mutate, .2);
//Create fitness function
eoEvalFuncPtr<plan_vector> eval(evaluate);
//Evaluate initial population and cout
apply<plan_vector > (eval, pop);
std::cout << pop << std::endl;
//Set GA for execution and execute
eoGenContinue<plan_vector> GenCount(5);
eoSGA<plan_vector> gga(select, crossover, .5, mutate, .1, eval, GenCount);
gga(pop);
//cout final population and end
std::cout << pop << std::endl;
std::cout << "The End" << std::endl;
}
a1.~vector();
a2.~vector();
b1.~vector();
b2.~vector();
You shall not destruct the vectors manually, otherwise the next time you try to access them (upon next call to the operator ()) you get undefined behavior.
Why do you call vector destructor manually?? You should let C++ call that for you. If you want to clear the vector use clear member function