dynamic dimension of arrays before the main function


Hello everybody,
Please let me know how can I define arrays with dynamic dimensions BEFORE THE MAIN FUNCTION STARTS. I need to use that arrays in classes defined before the main function.
Long story short, I need to read dimensions of some arrays from a text file which may be different each time we run the program, and these values or dimensions are used in classes defined before the main function starts. I can use #define the dimensions, but they should be variables to be read from a text

For example, the following program works fine as my array "p= new (nothrow) float[a]; " is defined inside the main function, but I need it to be defined before main for many reasons like it is used in my class which is defined before main, and many functions as well. This is my problem.






1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# include <iostream>
# include <fstream>
# include <new>
using namespace std;

int i, a;
float *p;
int main(int argc, char* argv[]) {
	ifstream f1;
	f1.open ("test.txt"); // assume there is number 12 saved in test.txt
	f1>> a; 
	f1.close();
	p= new (nothrow) float[a];

	if (p==nullptr)
	cout << "Error: memory could not be allocated";
	else {
	cout<< "Enter "<< a<< " float numbers"<< endl;
	for (i=0; i<a; i++) {
	cout << "Enter number: ";
	cin >> p[i];
	};
	};

 cout << "You have entered: ";
 for (i=0; i<a; i++)
 cout << p[i] << ", ";
	cout<< endl;
 delete[] p;

	system("pause");
	return 0;
};
What is wrong with the way you have done it? If there are classes that will need the array, then initialise those classes after you have initialised the array. You should update your post with more code in order for me to help more
If you must have arrays with dynamic dimensions allocated before main(),
wrap the code that reads the dimension(s) from a text file in a function.

Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <memory>
#include <fstream>
#include <new>

extern int* my_array ;
// better: extern std::unique_ptr< int[] > my_array ;

static std::size_t read_size_from_file( const char* path )
{
    std::size_t sz = 0 ;
    std::ifstream(path) >> sz ;
    return sz ;
}


int* my_array = new (std::nothrow) int[ read_size_from_file( "test.txt" ) ] ;
// or: std::unique_ptr< int[] > my_array
//                { new (std::nothrow) int[ read_size_from_file( "test.txt" ) ] } ;

// code which uses my_array 

int main()
{
    // ...
}


or like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <memory>
#include <fstream>
#include <new>

static int* allocate_with_size_from_file( const char* path )
{
    std::size_t sz = 0 ;
    std::ifstream(path) >> sz ;
    return new (std::nothrow) int[sz] ;
}

int* my_array = allocate_with_size_from_file( "test.txt" ) ;

// code which uses my_array

int main()
{
    // ...
}
Thank you for quick reply. Here is part of my program before main() that I have defined some constants (8 floats from inp to particlenumber) and works fine. The problem is I want these constants all variables to be read from a text file like test.txt instead of constants. I have used them in main and all defined functions. Please help me. I need to hand over the runtime to be able to work with different configuration set by text.txt.

# include <iostream>
# include <fstream>
# include <ostream>
# include <cmath>
# include <ctime>
# include <iomanip>

# define inp 64
# define hnumbers 20
# define onumbers 5
# define patterns 19
# define vpatterns 5
# define testpatterns 5
# define acceptablefitness 0.05
# define particlenumber 50

using namespace std;

int h,i,j,l,m,n,o,p;
float randomize(float Min, float Max) {
return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
};

class nodeclass {
private:
int k;
public:
float inputs[inp];
float weights[inp];
float bias;
float sum, y;

void setinputs (float in[inp]) {
for (k=0; k<inp; k++)
inputs[k]=in[k];
};
void setweights (float [inp]);
void setbias (float b) {
bias=b;
};
float getoutput(int inpnumbers) {
sum=0;
for (k=0; k<inpnumbers; k++) {
sum=sum+inputs[k]*weights[k];
};
sum=sum+bias;
y=1/(1+exp(-sum));
return y;
};
}; //class ends

void nodeclass::setweights(float w[inp]) {
for (k=0; k<inp; k++) {
weights[k]=w[k];
};
};

nodeclass nodes[hnumbers+onumbers];
float w1[inp];
float ep[onumbers];
float de[hnumbers+onumbers];
float herror[hnumbers];
float desiredoutputs[onumbers];
float normoriginal[patterns+vpatterns+testpatterns][inp+onumbers];

int main(int argc, char* argv[]) {
void ff(float in1[inp]);
float bep(float desiredoutputs[onumbers]);
float original[patterns+vpatterns+testpatterns][inp+onumbers];

//remaining codes here
retutrn 0;
};

//functions here


Last edited on
> The problem is I want these constants all variables to be read from a text file like test.txt.

Write a function as to do the run-time initialization (read from file etc.).

And use std::vector<> instead of dumb arrays.
http://www.mochima.com/tutorials/vectors.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <fstream>
#include <ostream>
#include <cmath>
#include <ctime>
#include <iomanip>
#include <vector>
#include <cstdlib> // std::rand

int inp = 64 ;
int hnumbers = 20 ;
int onumbers = 5 ;
int patterns = 19 ;
int vpatterns = 5 ;
int testpatterns = 5 ;
float acceptablefitness = 0.5 ;
int particlenumber = 50 ;

bool init( const char* path ) // run-time initialisation
{
    std::srand( std::time(nullptr) ) ;

    return std::ifstream(path) >> inp >> hnumbers >> onumbers
                                 >> patterns >> vpatterns >> testpatterns
                                 >> acceptablefitness >> particlenumber ;
}

const bool variables_were_read_from_file = init( "test.txt" ) ;

// ...

class nodeclass
{
    /* ... */
};

std::vector<nodeclass> nodes(hnumbers+onumbers);

std::vector<float> w1(inp);
std::vector<float> ep(onumbers);
std::vector<float> de(hnumbers+onumbers);
std::vector<float> herror(hnumbers);
std::vector<float> desiredoutputs(onumbers);

std::vector< std::vector<float> > normoriginal( patterns+vpatterns+testpatterns,
                                                   std::vector<float>(inp+onumbers) );

int main( int argc, char* argv[] )
{
    // ...
}

// ... 
Thanks, I got many errors like:
1>nn.cpp(20): error C2365: 'inp' : redefinition; previous definition was 'function' for int inp = 64 ;
or:
1>nn.cpp(53): error C2057: expected constant expression for float inputs[inp]; in class
or:
error C2057: expected constant expression, and 1>nn.cpp(54): error C2229: class 'nodeclass' has an illegal zero-sized array for float weights[inp]; in class
or:
1>nn.cpp(58): error C2057: expected constant expression at line void setinputs (float in[inp]) {
or:
1>nn.cpp(62): error C2440: 'initializing' : cannot convert from 'int (__cdecl *)(unsigned short)' to 'unsigned int' for void setweights (float [inp]); in class
.
.
or:
std::vector<float> in1[inp]; for std::vector<float> in1[inp];
and errors like this
I put the complete upper part of my prog here (this works fine):
# include <iostream>
# include <fstream>
# include <ostream>
# include <cmath>
# include <ctime>
# include <iomanip>


# define inp 64
# define hnumbers 20
# define onumbers 5

# define patterns 19
# define vpatterns 5
# define testpatterns 5
# define acceptablefitness 0.05
# define particlenumber 50

using namespace std;

int h,i,j,l,m,n,o,p;

float randomize(float Min, float Max) {
return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
};

class nodeclass {
private:
int k;
public:
float inputs[inp];
float weights[inp];
float bias;
float sum, y;

void setinputs (float in[inp]) {
for (k=0; k<inp; k++)
inputs[k]=in[k];
};
void setweights (float [inp]);
void setbias (float b) {
bias=b;
};
float getoutput(int inpnumbers) {
sum=0;
for (k=0; k<inpnumbers; k++) {
sum=sum+inputs[k]*weights[k];
};
sum=sum+bias;
y=1/(1+exp(-sum));
return y;
};
}; //class ends

void nodeclass::setweights(float w[inp]) {
for (k=0; k<inp; k++) {
weights[k]=w[k];
};
};

nodeclass nodes[hnumbers+onumbers];
float w1[inp];
float b1;
float in1[inp];
float epsum;
float *gbestweightsp;
float ep[onumbers];
float epp, epv;
float de[hnumbers+onumbers];
float herror[hnumbers];
float desiredoutputs[onumbers];
float normoriginal[patterns+vpatterns+testpatterns][inp+onumbers];

int main(int argc, char* argv[]) {
void ff(float in1[inp]);
float bep(float desiredoutputs[onumbers]);
float* pso(void);
float normalizein(float d, float min, float max);
float normalizeout(float d, float min, float max);
float denormalizeout(float d, float min, float max);
float original[patterns+vpatterns+testpatterns][inp+onumbers];
bool normalizationproess=false;
float sort[patterns][inp+onumbers];
float temp;
int iteration;
float vepsum;
float returnedepsum;
float w2[inp*hnumbers+hnumbers+onumbers*hnumbers+onumbers];
float min[inp+onumbers], max[inp+onumbers];
float desiredoutputs[onumbers];

srand((unsigned)time(NULL));

ifstream f1;
f1.open ("aa.txt");
ofstream f2;
f2.open ("out.txt");
ifstream f3;
f3.open ("gbest.txt");

for (i=0; i<patterns+vpatterns+testpatterns; i++) {
for (j=0; j<inp+onumbers; j++){
f1>> original[i][j];
if (original[i][j]>1) normalizationproess=true;
};
};
f1.close();
.
.
.
return 0;
};

void ff(float in1[inp]) {
for (i=0; i<hnumbers; i++)
nodes[i].setinputs(in1);
.
.
};

float bep(float desiredoutputs[onumbers]){
float lr= (float) 0.1;
epp=0;
for (i=hnumbers; i<hnumbers+onumbers; i++) {
ep[i-hnumbers]=desiredoutputs[i-hnumbers]-nodes[i].getoutput(hnumbers);
epp=epp+pow(ep[i-hnumbers],2);
.
.
};
// other functions goes here



This program works fine, unless commented parts (especially nodeclass does not work and each line gets error):
Please help me to fix them as well.

#include <iostream>
#include <fstream>
#include <ostream>
#include <cmath>
#include <ctime>
#include <iomanip>
#include <vector>
#include <cstdlib> // std::rand
using namespace std;


float inps = 64 ;
float hnumbers = 20 ;
float onumbers = 5 ;
float patterns = 19 ;
float vpatterns = 5 ;
float testpatterns = 5 ;
float acceptablefitness = 0.5 ;
float particlenumber = 50 ;

bool init( const char* path ) // run-time initialisation
{
std::srand( std::time(nullptr) ) ;

return std::ifstream(path) >> inps >> hnumbers >> onumbers
>> patterns >> vpatterns >> testpatterns
>> acceptablefitness >> particlenumber ;
}
const bool variables_were_read_from_file = init( "setup.txt" ) ;
int h,i,j,l,m,n,o,p;

float randomize(float Min, float Max) {
return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
};

/*class nodeclass {
private:
int k;
public:
std::vector<float> inputs(inps);
std::vector<float> weights(inps);
float bias;
float sum, y;

void setinputs (std::vector<float> in(inps)) {
for (k=0; k<inps; k++)
inputs[k]=in[k];
};

void setweights (std::vector<float> (inps));
void setbias (float b) {
bias=b;
};
float getoutput(int inpnumbers) {
sum=0;
for (k=0; k<inpnumbers; k++) {
sum=sum+inputs[k]*weights[k];
};
sum=sum+bias;
y=1/(1+exp(-sum));
return y;
};
}; //class ends

void nodeclass::setweights(std::vector<float> w(inps)) {
for (k=0; k<inps; k++) {
weights[k]=w[k];
};
}; */

//std::vector<nodeclass> nodes(hnumbers+onumbers);

std::vector<float> w1(inps);
std::vector<float> in1(inps);
std::vector<float> ep(onumbers);
std::vector<float> de(hnumbers+onumbers);
std::vector<float> herror(hnumbers);
std::vector<float> desiredoutputs(onumbers);
std::vector< std::vector<float> > normoriginal( patterns+vpatterns+testpatterns, std::vector<float> (inps+onumbers) );
float b1;
float epsum;
float *gbestweightsp;
float epp, epv;


int main( int argc, char* argv[] ) {
cout<< inps<< "\t"<< hnumbers<< "\t"<< onumbers<< "\t"<< patterns<< "\t"<< vpatterns<< "\t"<< testpatterns<< "\t"<< acceptablefitness<< "\t"<< particlenumber<< endl;

//void ff(std::vector<float> in1(inps));
//float bep(std::vector<float> desiredoutputs(onumbers));
float* pso(void);
float normalizein(float d, float min, float max);
float normalizeout(float d, float min, float max);
float denormalizeout(float d, float min, float max);
std::vector< std::vector<float> > original( patterns+vpatterns+testpatterns, std::vector<float> (inps+onumbers) );

bool normalizationproess=false;
std::vector< std::vector<float> > sort( patterns, std::vector<float> (inps+onumbers) );

float temp;
int iteration;
float vepsum;
float returnedepsum;
std::vector<float> w2(inps*hnumbers+hnumbers+onumbers*hnumbers+onumbers);
std::vector<float> min(inps+onumbers);// holds min of all inp+onumbers columns
std::vector<float> max(inps+onumbers); //holds max of all inp+onumbers columns
std::vector<float> desiredoutputs(onumbers);

srand((unsigned)time(NULL)); // random generator starter

ifstream f1;
f1.open ("aa.txt"); //open input file
ofstream f2;
f2.open ("out.txt"); //open output file
ifstream f3;
f3.open ("gbest.txt"); //holds gbest initialization weights of the network

for (i=0; i<patterns+vpatterns+testpatterns; i++) { //reads input data from aa.txt to original[][]
for (j=0; j<inps+onumbers; j++){
f1>> original[i][j];
//cout<< original[i][j];
if (original[i][j]>1) normalizationproess=true;
};
};
f1.close();

system("pause");
return 0;
};



Last edited on
This program works fine, unless commented parts (especially nodeclass does not work and each line gets error):
Please help me to fix them as well.

#include <iostream>
#include <fstream>
#include <ostream>
#include <cmath>
#include <ctime>
#include <iomanip>
#include <vector>
#include <cstdlib> // std::rand
using namespace std;


float inps = 64 ;
float hnumbers = 20 ;
float onumbers = 5 ;
float patterns = 19 ;
float vpatterns = 5 ;
float testpatterns = 5 ;
float acceptablefitness = 0.5 ;
float particlenumber = 50 ;

bool init( const char* path ) // run-time initialisation
{
std::srand( std::time(nullptr) ) ;

return std::ifstream(path) >> inps >> hnumbers >> onumbers
>> patterns >> vpatterns >> testpatterns
>> acceptablefitness >> particlenumber ;
}
const bool variables_were_read_from_file = init( "setup.txt" ) ;
int h,i,j,l,m,n,o,p;

float randomize(float Min, float Max) {
return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
};

/*class nodeclass {
private:
int k;
public:
std::vector<float> inputs(inps);
std::vector<float> weights(inps);
float bias;
float sum, y;

void setinputs (std::vector<float> in(inps)) {
for (k=0; k<inps; k++)
inputs[k]=in[k];
};

void setweights (std::vector<float> (inps));
void setbias (float b) {
bias=b;
};
float getoutput(int inpnumbers) {
sum=0;
for (k=0; k<inpnumbers; k++) {
sum=sum+inputs[k]*weights[k];
};
sum=sum+bias;
y=1/(1+exp(-sum));
return y;
};
}; //class ends

void nodeclass::setweights(std::vector<float> w(inps)) {
for (k=0; k<inps; k++) {
weights[k]=w[k];
};
}; */

//std::vector<nodeclass> nodes(hnumbers+onumbers);

std::vector<float> w1(inps);
std::vector<float> in1(inps);
std::vector<float> ep(onumbers);
std::vector<float> de(hnumbers+onumbers);
std::vector<float> herror(hnumbers);
std::vector<float> desiredoutputs(onumbers);
std::vector< std::vector<float> > normoriginal( patterns+vpatterns+testpatterns, std::vector<float> (inps+onumbers) );
float b1;
float epsum;
float *gbestweightsp;
float epp, epv;


int main( int argc, char* argv[] ) {
cout<< inps<< "\t"<< hnumbers<< "\t"<< onumbers<< "\t"<< patterns<< "\t"<< vpatterns<< "\t"<< testpatterns<< "\t"<< acceptablefitness<< "\t"<< particlenumber<< endl;

//void ff(std::vector<float> in1(inps));
//float bep(std::vector<float> desiredoutputs(onumbers));
float* pso(void);
float normalizein(float d, float min, float max);
float normalizeout(float d, float min, float max);
float denormalizeout(float d, float min, float max);
std::vector< std::vector<float> > original( patterns+vpatterns+testpatterns, std::vector<float> (inps+onumbers) );

bool normalizationproess=false;
std::vector< std::vector<float> > sort( patterns, std::vector<float> (inps+onumbers) );

float temp;
int iteration;
float vepsum;
float returnedepsum;
std::vector<float> w2(inps*hnumbers+hnumbers+onumbers*hnumbers+onumbers);
std::vector<float> min(inps+onumbers);// holds min of all inp+onumbers columns
std::vector<float> max(inps+onumbers); //holds max of all inp+onumbers columns
std::vector<float> desiredoutputs(onumbers);

srand((unsigned)time(NULL)); // random generator starter

ifstream f1;
f1.open ("aa.txt"); //open input file
ofstream f2;
f2.open ("out.txt"); //open output file
ifstream f3;
f3.open ("gbest.txt"); //holds gbest initialization weights of the network

for (i=0; i<patterns+vpatterns+testpatterns; i++) { //reads input data from aa.txt to original[][]
for (j=0; j<inps+onumbers; j++){
f1>> original[i][j];
//cout<< original[i][j];
if (original[i][j]>1) normalizationproess=true;
};
};
f1.close();

system("pause");
return 0;
};

Last edited on
> Now the program works, unless my class and the parts that are commented below:

You can't have a C-style array unless the size of the array is a constant known at compile-time.
Use std::vector<>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <fstream>
#include <ostream>
#include <cmath>
#include <ctime>
#include <iomanip>
#include <vector>
#include <cstdlib> // std::rand
using namespace std;


int /*float*/ inps = 64 ; // why is this a floating point number?
int /*float*/ hnumbers = 20 ;
int /*float*/ onumbers = 5 ;
int /*float*/ patterns = 19 ;
int /*float*/ vpatterns = 5 ;
int /*float*/ testpatterns = 5 ;
int acceptablefitness = 0.5 ;
int /*float*/ particlenumber = 50 ;

bool init( const char* path ) // run-time initialisation
{
    std::srand( std::time(nullptr) ) ;

    return std::ifstream(path) >> inps >> hnumbers >> onumbers
           >> patterns >> vpatterns >> testpatterns
           >> acceptablefitness >> particlenumber ;
}
const bool variables_were_read_from_file = init( "setup.txt" ) ;
int h,i,j,l,m,n,o,p;

float randomize(float Min, float Max)
{
    return ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
}

// ...

class nodeclass
{
private:
    int k;
public:
    // float inputs[inps];
    std::vector<float> inputs ; // [inps];
    // float weights[inps];
    std::vector<float> weights ; // [inps];
    float bias;
    float sum, y;

    /*
    void setinputs (float in[inps])
    {
        for (k=0; k<inps; k++)
            inputs[k]=in[k];
    };
    */
    void setinputs( const std::vector<float>& in ) { inputs = in ; }

    //void setweights (float [inps]);
    void setweights( const std::vector<float>& w ) { weights = w ; }
 
    // ...

// ... 

And likewise for the rest of the program.
Thank you it worked.
Those numbers are float because in text file we can assign them float numbers.
in the main function I have defined a function like:
void ff(float in1[inps]);
and I have changed it to:
void ff(std::vector<float> in1(inps));
but I get error:
1>dy-arr.cpp(82): error C2061: syntax error : identifier 'inps'

Thank you, was very helpful
> Those numbers are float because in text file we can assign them float numbers.

What do you do if in the file 25.73 is given for inps (the number of inputs)?
Hint:
a. Truncate: std::size_t n = inps ;
b. round: std::size_t n = std::lround(inps) ;


> and I have changed it to:
> void ff(std::vector<float> in1(inps));

First, read up on std::vector<> http://www.mochima.com/tutorials/vectors.html

1
2
3
void ff( std::vector<float> in1 ) ; // pass by value
// or void ff( std::vector<float>& in1 ) ; // pass by reference
// or void ff( const std::vector<float>& in1 ) ; // pass by reference to const 


Then, read up on how to post code on the programming forums:
http://www.cplusplus.com/articles/jEywvCM9/
Thank you very much. almost done, but one thing remaining.
I have the function float* pso(void) {}; that is called by gbestweightsp=pso(); inside the main(), and the pointer float *gbestweightsp; is defined before main() too;
float* pso(void) should point to the array gbestweights which is defined as:
std::vector<float> gbestweights(hnumbers*inps+hnumbers+onumbers*hnumbers+onumbers); inside the float* pso(void) function.

I can see the contents of the gbestweights array inside the function, but when wanted to return it at the end of the function by:
gbestweightsp=gbestweights;
return gbestweightsp;

the gbestweightsp=gbestweights; gets error:
1>dy-arr.cpp(560): error C2440: '=' : cannot convert from 'std::vector<_Ty>' to 'float *'

Last edited on
Repeat: use value semantics with std::vector<>

Return the vector by value (a copy is returned) or by reference if its lifetime extends beyond the end of the function.
can you put an example?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>
#include <iostream>
#include <iomanip>

std::vector<float> harmonic_progression( float a, float d, std::size_t nterms )
{
    std::vector<float> seq(nterms) ;

    // form the arithmetic progression
    for( std::size_t i = 0 ; i < nterms ; ++i ) seq[i] = a + i*d ;

    // take the reciprocals to get the harmonic progression
    for( float& v : seq ) v = 1/v ;

    return seq ; // return the sequence (by value)
}

int main()
{
   const std::vector<float> prog = harmonic_progression( 0.05, -0.0125, 9 ) ;

   std::cout << std::fixed << std::setprecision(2) ;
   for( float v : prog ) std::cout << std::showpos << v << ' ' ;
   std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/115bd87e4f202ba9
Thank you very much.
project done.
Topic archived. No new replies allowed.