Creating a dynamic array and sending it to a function.

ok, so I am a total noob :D I'm actually math major, only took intro to compsci.
I've been playing around with trying to create a genetic algorithm to calculate Ramsey numbers (yes, I realize it's way over my head, but I was hoping to at least get something relatively simple going...)
I made two functions, one generating two 2-D arrays (using constant variables) and one calculating the number of subsets.
Now I want to change it so the user inputs the size of the 2-D array. Then that array is sent to the function which fills it with 0's and 1's. Then it's sent to the second function to find the number of subsets.
I've been googling dynamic arrays and sending them in and out of functions for a couple days now, but I can't seem to figure it out :(

Could someone please nudge me in the right direction as to how to fix this code please?
EDIT: ok, now it at least launches XD but crashes after i input the size of array :|
Any help is appreciated.

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "stdafx.h"
#include <iomanip>
#include <iostream>
#include <stdio.h>
using namespace std;


void displayChart(int ** chart, int&, int&);
void fitnessChart(int ** chart, int&, int&);

int main()
{
	int rows, cols, v;

	cout << "Enter the number of vertices :" << endl;
	cin >> v;
	rows = v;
	cols = v;
	
	int ** chart;

	chart = new int*[rows];											// allocation

	for(int r = 0; r < rows; r++)
	{
		chart[r] = new int[cols];
	}

	for(int c = 0; c < cols; c++)									// initialization
	{
		for(int r = 0; r < rows; r++)
		{
			chart[r][c] = 0;
		}
	}

	displayChart(chart, v, v);
	fitnessChart(chart, v, v);

	system ("pause");

return 0;
}


void displayChart(int ** chart, int& r, int& c)										// displayChart1 function body
{
	int e, i, j;
	for (i=0; i<r; i++)
	{
		for (j=0; j<r; j++)
		{
			e = rand() %2;
				if (i == j)												// no loops in the graph allowed
			{
				chart[i][j] = 9;										// identify a loop
				break;
			}
			else
			{
			chart[i][j] = e;
			chart[j][i] = e;
				}
			
		}
	}
	cout << "   1 2 3 4\n__________" << endl
		 << "1    " << chart[0][1] << " " << chart[0][2] << " " << chart[0][3] << endl	
		 << "2  " << chart[1][0] << "   "<< chart[1][2] << " " << chart[1][3] << endl
		 << "3  " << chart[2][0] << " " << chart[2][1] << "   "<< chart[2][3] << endl		
		 << "4  " << chart[3][0] << " " << chart[3][1] << " " << chart[3][2] << endl << endl;

}

void fitnessChart(int ** chart, int& r, int& c)										// fitnessChart2 function body
{
	int count=0, match, i=0, j=1;

	for (j; j<c; j++)
	{
		match = chart[i][j];
		i=j;
		
		for (j; j<c; j++)
		{
			if (chart[i][j+1] == match)
			{
				if (chart[i][j+1] == match)
				{
					count++;
				}
			}
		}
	}
	cout << count << endl;
}
Last edited on
In displayChart
You are using r as the upper bound for both row and column indexing.
This won't make it crash since you are inputting a square matrix - but is it right?

I don't understand fitnessChart at all but it seems likely that the index [i][j+1] is overstepping the array bounds and causing the crash.

A poor mans debugging tool is to stick output messages in your code so you can see where the code gets up to and what some of the variables are.

To do this use cerr (not cout). This is because cerr is not buffered and so your message comes straight out on the terminal. If you use cout you will not see all output up to the moment of the crash.

oh, i got it ... i don't know what i did, only changed some formatting, but i guess that did it X.x ...

You wouldn't happen to know how, instead of having just one matrix, i could have user input the number of matrices to be generated, would you?
I would like to be able to produce and store for further applications several matrices, just not sure how to write that function >.< ...
thanks so much for your help!
You could create a matrix class or struct. Then in your main function, you can create an array (or vector, list, etc.) of your matrix class/struct.
oh ... i don't know how to do that >.> ... but thanks anyways! I'll go see if i can google some instructions :]
ok, so i tried something different but now I can't figure out how to pass the array to the function >.<
what am I doing wrong?

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

#include "stdafx.h"
#include <iomanip>
#include <iostream>
#include <stdio.h>
#include<vector>

using namespace std;

void fitnessChart(vector<int>&, int&, int&);

int main(int argc, char* argv[])
{
    int vertices;
	const int initial_value = 0;
    int i;
	std::cout << "Enter the number of vertices:" << std::endl;
	std::cin >> vertices;
	std::cout << "Enter the size of the population:" << std::endl;
    std::cin >> i;

    std::vector<int> sub_sub_array(vertices, initial_value);
    std::vector<std::vector<int> > sub_array(vertices, sub_sub_array);
    std::vector<std::vector<std::vector<int> > > array(i, sub_array);

	int e;
    for(int i = 0; i < vertices; ++i)
    {
        for(int j = 0; j < vertices; ++j)
        {
            for(int k = 0; k < vertices; ++k)
            {
			e = rand() %2;
				if (j == k)							
				{
				array[i][j][k] = 9;
				break;
				}
				else
				{
					array[i][j][k] = e;
					array[i][k][j] = e;
				}
			
			}
		}
	}



    // Print out the full array contents
    for(int i = 0; i < vertices; ++i)
    {
        for(int j = 0; j < vertices; ++j)
        {
            for(int k = 0; k < vertices; ++k)
            {
				if(j!=k)
				{
					std::cout << " " << array[i][j][k] << " ";
				}
				else
					std::cout << " - "; 
            }
            std::cout << "\n";
        }
        std::cout << "\n";
    }

    for(int i = 0; i < vertices; ++i)
    {
		fitnessChart(array, i, vertices);
	}

	system ("pause");
}

void fitnessChart(vector<int>& array, int& num, int& vertices)
{
	int count=0, match, i=num, j=0, k=1;

	for(int k = 0; k < vertices; k++)
    {
		match = array[i][j][k];
		j=k;
		
		for(int k = 0; k < vertices; k++)
        {
			if (array[i][j][k+1] == match)
			{
				if (array[i][j][k+1] == match)
				{
					count++;
				}
			}
		}
	}
	cout << count << endl;
}
Since you are dynamically allocating multidimensional arrays already you could go one level deeper with it and allocate an array of 2d arrays. It appears that all of your matrices are square. Would each matrix have the same dimension?
I'll assume so for the sake of simplicity in the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int numMatrices=0, v=0;
cout << "How many matrices?" ;
cin >> numMatrices;
cout << "How many rows in each matrix?" ;
cin >> v;

// allocation and initialization
int*** charts = new int**[numMatrices];
for(int i = 0; i < numMatrices; i++)
{
	charts[i] = new int*[v];
        for(int j = 0; j < v; j++)
       { 
              charts[i][j] = new int[v];
              for(int k = 0; k < v; k++)
                  charts[i][j][k] = 0;
        }
}

// pass the 3rd matrix to your existing function
displayChart(charts[2], v, v);


Or, since it appears that your displayChart() performs the actual initialization, just stick it in the above code like so:
1
2
3
4
5
6
7
8
int*** charts = new int**[numMatrices];
for(int i = 0; i < numMatrices; i++)
{
	charts[i] = new int*[v];
        for(int j = 0; j < v; j++)        
              charts[i][j] = new int[v];
        displayChart(charts[i], v, v);
}


Don't forget to cleanup the memory when you are done with it!
1
2
3
4
5
6
7
for(int i = 0; i < numMatrices; i++)
{	
        for(int j = 0; j < v; j++)        
              delete [] charts[i][j];
        delete [] charts[i];
}
delete [] charts;

Warning. This code not tested. I could have boned something here.
EDIT: I now see that you posted with a vector based solution. Most people would recommend that over dynamic arrays.
I think you would need to pass a
std::vector<std::vector<int> >& to your function now as
array[index]
Last edited on
oh wow, that is one nice compact pretty code :D
I'm still getting used to the fact that the way to create multiple arrays is to add another dimension to the existing one @.@ ...

but as far as the version with the vectors, what is array[index]? >.> ... i've had it as just array[i][j][k] before and it said that same thing - "identifier is unidentified"

also here
match = array[i][j][k];
it doesn't like 'k' for some reason ... says "expression must have pointer-to-object type"
Last edited on
If your goal is to actually calculate something mathematical rather than to implement all this stuff yourself, get a library. boost.ublas and eigen are pretty good:
http://www.boost.org/doc/libs/release/libs/numeric/ublas/doc/index.htm
http://eigen.tuxfamily.org/index.php?title=Main_Page
Last edited on
oo, that looks useful! :D My programming skills are pretty minimal @.@ I'm really just doing this out of curiosity between math HW, and don't expect anything mind-blowing to come out of it XD
I'll definitely check those out tho. This whole trying to reinvent the bicycle isn't working out too great >.<
Thanks, mate!

edit: one more stoopid question ... how do i add a library? XD
Last edited on
Some of the dimensions of your objects are being handled incorrectly.
You have created a 3d vector called array. I think of a 2d vector as an array. To reduce confusion (hopefully) let me refer to the 3d vector as a vector of arrays, hence:
std::vector<std::vector<std::vector<int> > > arrayVec(i, sub_array);
Now, arrayVec[2] refers to the 3rd array stored in arrayVec.

You want to pass a 2d array to a function, so the function signature should be:
void fitnessChart(vector<vector<int>>& array)
The object passed is just a 2d array so you use only 2 subscripts to get at the values of the elements. Example: if (array[i][j] == match).
You would call the function like so:
fitnessChart( arrayVec[2] );// passing the 3rd array in arrayVec.
One advantage to using vectors is that you don't need to pass the # of rows (v) because that info. can be gotten from the vectors size().
Example:
1
2
3
4
5
6
initme( vector<vector<int>>& array )
{
    for(unsigned int i=0; i<array.size(); ++i)
         for(unsigned int j=0; j<array[i].size(); ++j)
             array[i][j] = 0;
}

Hope that helps, if you haven't already moved on to Cubbis suggested tools!
Last edited on
*headscratch* ... hmmm ... but i thought the 'i' variable is what identifies the 3rd 2d array (and how we're able to call it) and 'j' and 'k' are rows and columns respectively ... so where does that come in in the call function?
sorry i'm slow %\
edit: it compiles but i get a runtime error: Expression: vector subscript out of range
Last edited on
You are passing a particular 2d array stored in the 3d vector to fitnessChart() by supplying the 1st index only. Was this your 1st question?

The number of rows and columns does not need to be passed to the function because that data can be gotten from the vector size(). See my example initme() in my last post.

it compiles but i get a runtime error: Expression: vector subscript out of range


I'm guessing that this was caused by lines 27 and/or 52. The upper limit in those for loops should be "size of population" (read in as i on line 20) not vertices. Again, using the vector size() allows you to avoid this issue.
Lines 27-31 could be:
1
2
3
4
5
for(int i = 0; i < array.size(); ++i)// # of 2d arrays in array
    {
        for(int j = 0; j < array[i].size(); ++j)// # of rows in 2d array # i
        {
            for(int k = 0; k < array[i][j].size(); ++k)// # of elements in row j of 2d array # i 
You are passing a particular 2d array stored in the 3d vector to fitnessChart() by supplying the 1st index only. Was this your 1st question?


exactly! :D

I'm guessing that this was caused by lines 27 and/or 52. The upper limit in those for loops should be "size of population"


no, the function has to iterate as many times as there are rows/columns in the 2d matrix, not the total number of 2d matrices. These could be different.
EDIT: oh wait, no, you're right ... i was looking at fitness function, that's where my comment applies >.<

also, what is the 'array' part in
1
2
3
4
    for(int i = 0; i < vertices; i++)
    {
		fitnessChart(array[2], vertices);
	}


says no suitable conversion from stdblahblah <int> to stdblahblah <int&>

thanks for bearing with me :3 this is really fun actually = ^.^ = for me at least X3 i like learning new stuffs :D

EDIT: still getting "vector subscript out of range"
blarg ... gonna go stare at it some more

here's what it looks like now btw, pretty much same
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

#include "stdafx.h"
#include <iomanip>
#include <iostream>
#include <stdio.h>
#include<vector>

using namespace std;

void fitnessChart(std::vector<std::vector<int> > array);

int main(int argc, char* argv[])
{
    int vertices;
	const int initial_value = 0;
    int i;
	std::cout << "Enter the number of vertices:" << std::endl;
	std::cin >> vertices;
	std::cout << "Enter the size of the population:" << std::endl;
    std::cin >> i;

    std::vector<int> sub_sub_array(vertices, initial_value);
    std::vector<std::vector<int> > sub_array(vertices, sub_sub_array);
    std::vector<std::vector<std::vector<int> > > array(i, sub_array);

	int e;
    for(int i = 0; i < array.size(); ++i)
    {
        for(int j = 0; j < array[i].size(); ++j)
        {
            for(int k = 0; k < array[i][j].size(); ++k)
			{
			e = rand() %2;

				if (j == k)	
				{
				array[i][j][k] = 9;	
				break;
				}
				else
				{
					array[i][j][k] = e;
					array[i][k][j] = e;
				}
			
			}
		}
	}



    // Print out the full array contents
    for(int i = 0; i < array.size(); ++i)
    {
        for(int j = 0; j < array[i].size(); ++j)
        {
            for(int k = 0; k < array[i][j].size(); ++k)
			{
				if(j!=k)
				{
					std::cout << " " << array[i][j][k] << " ";
				}
				else
					std::cout << " - "; 
            }
            std::cout << "\n";
        }
        std::cout << "\n";
    }

    for(int i = 0; i < vertices; i++)
    {
		fitnessChart(array[2]);
	}

	system ("pause");
}

void fitnessChart(std::vector<std::vector<int> >array)
{
	int count=0, match, j=0;

	for(unsigned int k = 0; k < array[k].size(); ++k)
			{
		match = array[j][k];
		j=k;
		
		for(unsigned int k = 0; k < array[k].size(); ++k)
			if (array[j][k+1] == match)
			{
				if (array[j][k+1] == match)
				{
					count++;
				}
			}
		}
	}
	cout << count << endl;
}


here's what needs to happen:
test drive with 4 vertices and just one 2d matrix

after the first function randomly filled the array with 1's and 0's the fitness function checks to see if there is a subgraph of 3 vertices as such:
if array[a][b]=1 it means vertices a and b are connected:


a--1--b
| \ _ / |
0 1x0 1
| /__\ |
c--1--d


(pardon the shitty illustration +.+ ... no trailing spaces >.<)
here vertices a, b, d are connected and create a subgraph ('x' is the intersection of two inner diagonals, not a vertex).

yet another EDIT: asked around, people keep saying it works on their compiler, but freaks out in my Visual Studio ... this is unsettling :\ ...
Last edited on
no, the function has to iterate as many times as there are rows/columns in the 2d matrix, not the total number of 2d matrices. These could be different.

This is true for the 2 inner loops, but the limit for the outermost loops (lines 27 and 52) is the # of matrices stored, which is "size of population".


also, what is the 'array' part in
for(int i = 0; i < vertices; i++)
{
fitnessChart(array[2], vertices);
}

'array' is the name for the 3d vector you declared to exist on line 24.
The '2' in array[2] is just an example value. You should use the values needed. eg array[0], or maybe array[i] if you are processing all of the matrices in a loop.

The only code I have to look at is from 4 of your posts ago. The above code doesn't appear there so I can't judge the context. Please re post any newer code so I can see what you are currently trying to do.

says no suitable conversion from stdblahblah <int> to stdblahblah <int&>


Maybe you didn't change the argument taken by fitnessChart() from vector<int>& to vector<vector<int>>& as is needed? Please post error messages verbatim. 'stdblahblah' is not informative.

Glad you're having fun with this.

is there a way to upload pics here? >.> ... i dun see one <.<
but here's a screenshot
http://www.4shared.com/photo/FY_6SEYt/Capture.html
and the code in the previous post is what it looks like nao :3

EDIT: I've been told to get codeblocks = -_- = ...
Last edited on
test drive with 4 vertices and just one 2d matrix

Then yes, array[2] would be out of range. Only array[0] would exist.
Try this to replace lines 71-74:
1
2
3
4
for(int i = 0; i < array.size(); i++)
    {
		fitnessChart(array[i]);
	}

You have another out of range problem in fitnessChart().
Lines 88-95:
1
2
3
4
5
6
7
8
for(unsigned int k = 0; k < array[k].size(); ++k)
			if (array[j][k+1] == match)// k+1 will go one too high!!!
			{
				if (array[j][k+1] == match)// here too.
				{
					count++;
				}
			}

Another potential out of range error exists on line 43 in main()
array[i][k][j] = e;// k and j are reversed
You may need to reverse those subscript values like that but the matrix had better be square!
Then yes, array[2] would be out of range. Only array[0] would exist.

yeah, someone else said the same thing too

in lines 88-95 i think i had k++ changed to ++k at some point ... it should be k++

and my matrices will always be square, so it's ok to reverse k and j :D

i'm going to try this in codeblocks now ... because apparently VS is acting up ...
here is the code that someone just now cleaned up and it works in CB but not VS
http://ideone.com/rbtqp

no idea why :| mildly discouraging .... :|
Last edited on
ok, so can someone please explain to me why this works (doesn't crash) with every number (at least ones i've tried so far) EXCEPT (3,2)(as in 3 for the first input, and 3 for the second)(3,3)(3,4)etc. and (5,3)? X.x ... something about 3's it doesn't like ...
i'ma lose my gawddamm mind with this thing XD
http://ideone.com/JDLSW

unless the compiler is freaking out again ... but i did switch to CodeBlocks and it's being pretty consistent so idunno XD

EDIT: also the fitness function doesn't seem to be working properly :\ ...
for a 4x4 matrix like this:

- 1 1 1
1 - 1 1
1 1 - 1
1 1 1-

the count variable should end up being 4, not 2, which is what i'm getting ...
you can check to make sure i'm not crazy XD 4x4 matrix of all 1's would be a 4-gon where every vertex is connected to every other vertex... you get 4 triangles...
i tried just writing on the paper what fitness function would do given that matrix and it seems like count should be 4 in the end, but it's not for some reason >.< ... unless i'm missing something ... it is 2am ... i'm going to bed, mebe i'll dream up how to fix this XD ...
night, pplz
Last edited on
yeah, so i definitely messed up my algorithm >.< would anyone like to give it a go based on the (hopefully understandable) explanation above?
Topic archived. No new replies allowed.