Passing arrays as parameters

while avoiding segmentation errors

Page 1 of 1

8 Replies - 22827 Views - Last Post: 20 April 2008 - 11:29 PM Rate Topic: -----

#1 Vegter  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 21-September 05

Passing arrays as parameters

Posted 19 October 2005 - 02:47 PM

Hi

I'm trying to pass a 33*33 matrix as a parameter to a second function, but I keep getting a segmentation error. I think I am doing something obvioustly wrong, but I'm still learning and this is a big part of what I am struggling with.


/* This method determines the rank of a binary matrix.
   The matrix is reduced to upper triangular form using
   forward row operations and the operation is repeated
   using backward row operations in order to arrive at
   a matrix in triangular form.  The rank is then taken
   to be the number of nonzero rows in the matrix.  

	m = The size of the matrix (m*m)
	Matrix = The matrix which we want the rank of  */

int MatrixRand(boolean **Matrix, int m) {

	int i, j, k, row, col, rank;
	boolean found, tmp;

	// Forward operations
	
        i = 1;  // Step 1
	while (i <= m-1) {

  // Step 2
  found = TRUE;
  printf("StatisticalFunctions, before...\n");
  if (Matrix[i][i] == 0) {
 	 printf("StatisticalFunctions, middel...\n");
 	 // Search for a row with a leading 1
 	 found = FALSE;
 	 k = i+1;
 	 while ((found == 0) && (k<=m)) {
    if (Matrix[k][i] == 1) {
   	 found = TRUE;
   	 // Swap all the elements of row i and k
   	 for (j = 1; j <= m; j++) {
      tmp = Matrix[i][j];
      Matrix[i][j] = Matrix[k][j];
      Matrix[k][j] = tmp;
   	 }
    }
    k++;
 	 }
  }
  printf("StatisticalFunctions, after...\n");

  if (found == 1) {
 	 // Step 3

 	 // Search for any subsequent row with a 1 in the ith column
 	 row = i+1;
 	 col = i;
 	 while (row <= m) {
    if (Matrix[row][col] == 1) {
   	 // XOR every element in this row with the ith row
   	 for (j = 1; j <= m; j++) {
      Matrix[row][j] = XOR(Matrix[row][j],Matrix[i][j]);
   	 }
    }
    row++;
 	 }
 	 
  } // if (found)

  // Step 4
  i++;

	} // while

	// Backward operations
	
	i = m;  // Step 1
	
	while (i > 2) {
  found = TRUE;
  if (Matrix[i][i] == 0) {  // Step 2
  
 	 found = FALSE;
 	 k = i-1;
 	 while ((found == 0) && (k<=m)) {
    if (Matrix[k][i] == 1) {
   	 found = TRUE;
   	 // Swap all the elements of row i and k
   	 for (j = 1; j <= m; j++) {
      tmp = Matrix[i][j];
      Matrix[i][j] = Matrix[k][j];
      Matrix[k][j] = tmp;
   	 }
    }	
    k--;
 	 }
 	 
  }

  if (found == 1) {
 	 // Step 3
 	 row = i-1;
 	 col = i;
 	 while (row >= 1) {
    if (Matrix[row][col] == 1) {
   	 // XOR every element in this row with the ith row
   	 for (j = 1; j <= m; j++) {
      Matrix[row][j] = XOR(Matrix[row][j],Matrix[i][j]);
   	 }
    }
    row--;
 	 }	
  }  // if found

  // Step 4
  i--;
  
	}  // while

	// The rank of the matrix = the number of non-zero rows
	rank = 0;
	for (j = 1; j <= m; j++) {
  found = FALSE;
  for (k = 1; k <= m; k++) {
 	 if (Matrix[j][k] == 1) {
    found = TRUE;  // The row is non-zero
 	 }
  }
  if (found == 1) { rank++; }
	}
	return rank;
	
};

/* The focus of this test is the rank of the disjoint sub-matrices of the 
   sequence.  This test checks for linear dependance among fixed length
   substrings of the sequence.  For implementation purposes, matrices
   of size 32*32 are used.

	n = The number of bits in the sequence */

boolean BinaryMatrixRankTest(long n) {

	int Fm, Fm1, i, j, rank, N, N2;
	double Xobs, P;
	boolean Matrix[33][33];  // The 0-index is left unused
	
	N = n/(1024);  // Throw away bits that do not make up a full matrix

	if (n < 38912) {
  printf("Incorrect parameters. ");
  return FALSE;
	}

	N2 = 0;
	// Fill the matrix
	while (n >= 1024) { // 32*32 = 1024
  for (i = 1; i <= 32; i++) {
 	 for (j = 1; j <= 32; j++) {
    Matrix[i][j] = getNextBoolean();
    n--;
 	 }
  }
  printf("Before...\n");
  rank = MatrixRand(Matrix,32);
  printf("After...\n");
  switch (rank) {
 	 case 32 : Fm++; break;
 	 case 31 : Fm1++; break;
  }
  N2++;
	}
	
	printf("Precomputed N: %d\n",N);
	printf("Postcomputed N: %d\n",N2);

	Xobs = pow(Fm - 0.2888*N,2)/(0.2888*N) + pow(Fm1 - 0.5776*N,2)/(0.5776*N)
   	 + pow(N - Fm - Fm1 - 0.1336*N,2)/(0.1336*N); 

	P = chidist(Xobs,2);

	if (P < 0.01) {
  // The sequence is non-random
  return FALSE;
	} else {
  // The sequence is random
  return TRUE;
	}

};



I get an segmentation error the first time I try to access the array in the MatrixRand function. I would basically like to send the second function a pointer to the Matrix. What am I doing wrong? Please HELP!

Is This A Good Question/Topic? 0
  • +

Replies To: Passing arrays as parameters

#2 damoun  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 36
  • Joined: 07-August 05

Re: Passing arrays as parameters

Posted 19 October 2005 - 07:19 PM

some points on arrays and using arrays as arguments of functions:

1)in C++(and I think in C as well) you can not use an array as argument of a function nor can a function return ar array.

2) some points about arrays, pointers and string literals :
C++ interpretes the name of an array as a pointer pointing to its first element(two exception to this rule is when you declare an array, in this case the name of the array is interpreted as a memory lable , the other exception is when an array name is used with the sizeof() operator
in this case the sizeof operator will return the memory size of the array in bytes)
C++ also interprets a string literal as a pointer, pointing to its first element(ie: its first character), that is why we can write things like this:
char * p_char = "Hello , World!";
it is however a good idea when assigning a string literal to a pointer, to declare p_char to be a pointer to const char,
so we will not be able to use the pointer p_char to alter the value of the object or (data) that the pointer points to. an attempt to change the value of a string literal will cause a runtime error.
but if you try to alter a value pointed to by a pointer to const you will get a compile time error.
(so its is better to write this: const char * p_char = "Hello, World!";)

3)an example of an array:
double list[30];
so in C++ list(the name of the array) is interpreted as a pointer pointing to the first element of the array, in this case list points to
list[0](first element of the array list).

so list is in fact equivelent to double * p_double (p_double is a pointer to type double)
so to pass the above array(double list[30]) into a function we can do it indirectly this way:

void a_function(double * a_pointer , int array_size)
{
//this function will display the content of the array passed into it
for (int i = 0; i < array_size; ++i)
std::cout << a_pointer[i];
}


4)some notes with the subscript notation:
for any pointer (and since array names are actually interpreted as pointers all of the following are equivelent:)
consider the following:
char a_char = 'd';
char * p_char = &a_char;//& is the address operator
double list[i];

i)to access the object(or character) pointed to by the pointer p_char
we use the indirection operator like so:

*p_char is equal to the value of the character varible a_char , and in this case the character 'd'.

ii)so with this knowledge and the fact that the name of an array is interpreted as a pointer pointing to the firts of the array.
list[0](the first element of the array) can actually be written as
*list (using the indirection operator).

iii)One of the powerful features of pointers is that we can increment and decrement the value of a pointer.

so the expresion:
double * p_pointer = list;
p_pointer = p_pointer + 1;
now the value of the pointer p_pointer has been incremented by the number of bytes, a double value takes up in computer memory, (in most cases by 8 bytes).
and so now p_pointer points to the second element of the array and if we dereference the pointer p_pointer(ie: use the indirection operator onto the pointer p_pointer) we get the seconsd element of the array.
so:
list[1] , can also be written as *p_pointer , or it can be written as
*(list + 1) (note here that we are using the indirection operator on all pointer that now points to the second element of the array list)
so we can keep going:
(list + 2) will be a pointer pointing to the third element of the array so
list[2] can also be written as *(list + 2)
and the last element of the array can be written as both list[29]
or *(list + 29).
so what the subscript ([]) notation means is this.
list[i] (where i is an integer) means *(list + i)

5) so what if we have an array of pointers say:
double * an_array[10]; // array of 10 pointers to type double

againg the name of a pointer is interpreted as a pointer pointing to the first element of the array, so an_array is a pointer that points to a pointer to type double.
so to assaign an_array to a pointer an aproprate varible will be this:
double ** p_apointer = an_array;

6)ro declare a two dimentional array of doubles we write this:
double a_array[3][10];
the above array is an array of 3 , arrays of 10 doubles.
ie:the above array has 3 elements, each element is an array of 10 doubles.
so in this case a_array is a pointer pointing to its first element (namely to an array of 10 doubles).
an appropriate varible to assaign the value of a_array to would be:
double (*p_array)[10] = a_array;
so p_array is declared to be a pointer, to an array of 10 doubles.
we can also declare another pointer pointing to a different array
char (*p_char)[123];
p_char is a pointer that points to an array of 123 cahracters.
now going back to the pointer p_array,
to access the first element of the array that the pointer points to we can write:
**p_array , or *p_array[0] , or p_array[0][0].
and the reson for this is that p_array is a pointer an array(in the above case to a_array) but a_array is actually a pointer pointing to its fisrt element namely to the array of 10 doubles.
so *p_array is the same *a_array , (which is the first array element of the array a_array)
and **p_array is the same a **a_array which is the fisrt element of the fisrt array element of the array a_array.

write a few arrays and experiment with it untill you get the idea.

//hope this helps.
Was This Post Helpful? 0
  • +
  • -

#3 Vegter  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 21-September 05

Re: Passing arrays as parameters

Posted 20 October 2005 - 03:20 AM

Wow, that's a LOT of info :huh:

Anyways, I think my line of thinking is still correct. I declare a 2-dimensional array of booleans, fill the array, and then call the second function with the pointer to the first element in the array. But for some reason it is just not working. I'm sure all I'm missing is a * or a & somewhere, but I just can't see it. Anyways, if no-one here can help me I'll just experiment with it until I get it right.

The fact of the matter is that 2-dimensional arrays are used just as 1-dimensional arrays are used. They are stored linearly in memory (i.e. one after the other). But obvioustly the pointer is not being passed correctly...
Was This Post Helpful? 0
  • +
  • -

#4 Amadeus  Icon User is offline

  • g+ + -o drink whiskey.cpp
  • member icon

Reputation: 248
  • View blog
  • Posts: 13,506
  • Joined: 12-July 02

Re: Passing arrays as parameters

Posted 20 October 2005 - 04:05 AM

Vegter, you are correct, you can certainly pass the pointer variable to the first array element to a function...I'm not near a compiler at the moment, will try to have a look later, it's likely just a matter of syntax.

While it is true that you don't pass arrays directly, the effect of passing the pointer to the first element is the same as passing by reference.
Was This Post Helpful? 0
  • +
  • -

#5 Vegter  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 21-September 05

Re: Passing arrays as parameters

Posted 20 October 2005 - 11:00 AM

Quote

Vegter, you are correct, you can certainly pass the pointer variable to the first array element to a function...I'm not near a compiler at the moment, will try to have a look later, it's likely just a matter of syntax.

While it is true that you don't pass arrays directly, the effect of passing the pointer to the first element is the same as passing by reference.


I totally agree. I think my idea is sound, I'm just messing up with the syntax.
Was This Post Helpful? 0
  • +
  • -

#6 Vegter  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 21-September 05

Re: Passing arrays as parameters

Posted 22 October 2005 - 04:45 AM

I saw someone declaring a pointer to a 2-dimensional array as
int MatrixRand(boolean** Matrix, int n);



But this doesn't solve my problem, I still get a segmentation error...
Was This Post Helpful? 0
  • +
  • -

#7 Vegter  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 77
  • Joined: 21-September 05

Re: Passing arrays as parameters

Posted 24 October 2005 - 12:40 PM

Ok, if anyone cares, I solved the problem by using calloc and defining the initial Matrix as a pointer. I then step through the entire matrix and call calloc for each row... Then it works. I still don't understand why my method didn't work.
Was This Post Helpful? 0
  • +
  • -

#8 johnss  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 20-April 08

Re: Passing arrays as parameters

Posted 20 April 2008 - 10:52 PM

View PostVegter, on 24 Oct, 2005 - 12:40 PM, said:

Ok, if anyone cares, I solved the problem by using calloc and defining the initial Matrix as a pointer. I then step through the entire matrix and call calloc for each row... Then it works. I still don't understand why my method didn't work.


Because you should have used boolean* matrix instead of boolean** matrix

A 2 dimensionnal array in C works like this: let's say you have int[4][4] matrix

and the matrix looks like this:
[[ 1, 2, 3, 4] << matrix[0][0-3]
[ 5, 6, 7, 8] << matrix[1][0-3]
[ 9, 10, 11, 12] << matrix[2][0-3]
[13, 14, 15, 16]] << matrix[3][0-3]


In memory it looks like this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16


So when you "pass" your matrix array you're passing the pointer to the 1. It's not a pointer to a pointer like you were assuming.
Was This Post Helpful? 0
  • +
  • -

#9 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3093
  • View blog
  • Posts: 19,139
  • Joined: 14-September 07

Re: Passing arrays as parameters

Posted 20 April 2008 - 11:29 PM

This thread is over 2 years old.......
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1