Solved

C - Generating 5x5 array

Posted on 2006-11-04
7
1,045 Views
Last Modified: 2008-02-01
Using C, I am trying to generate a 5x5 array filled with random numbers from 0.0 to 1.0 (including 0.0 and 1.0).  Each row should add up to 1, which is a markov table.  The output should look similar as follows:
Row 1 [ 0.3 0.4 0.1 0.0 0.2 ]
Row 2 [ 0.0 1.0 0.0 0.0 0.0 ]
Row 3 [ 0.8 0.0 0.0 0.2 0.0 ]
Row 4 [ 0.1 0.6. 0.2 0.0 0.1]
Row 5 [ 0.9 0.0 0.0 0.0 0.0 ]

I was going to fill the table with random numbers, then normalize them (divide each by the row's sum).  I was able to generate the random numbers, but am getting a segmentation fault or mismatches from storing in the array and printing it later.  Here is the code (compiled by CC).

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

/*
 * MAIN FUNCTION - Generate Random Markov Table
 */
int main() {

/* Set Random Seed from System Time for rand() */
srand(time(NULL));

/* Create Markov array */
int MAXROW = 4;
int MAXCOL = 4;
float arrMarkov[MAXROW][MAXCOL];

/* Fill Markov array with Random numbers */
int row;
int col;
float rnum;
for (row = 0; row <= MAXROW; row++) {
    printf("Row %i [", row);
    for (col = 0; col <= MAXCOL; col++) {
        rnum = (float)(rand() % 11) / 10;
        arrMarkov[row][col] = rnum;
        printf("%f ", rnum);
    }
    printf("]\n");
}

/* Print array */
printf("\n");
for (row = 0; row <= MAXROW; row++) {
    printf("Row %i [", row);
    for (col = 0; col <= MAXCOL; col++) {
        printf("%f ", arrMarkov[row][col]);
    }
    printf("]\n");
}

return 0;
}
0
Comment
Question by:deadite
  • 2
  • 2
  • 2
  • +1
7 Comments
 
LVL 84

Accepted Solution

by:
ozo earned 125 total points
ID: 17875130
float arrMarkov[MAXROW+1][MAXCOL+1];
0
 
LVL 84

Expert Comment

by:ozo
ID: 17875145
#define MAXROW  4
#define MAXCOL 4
float arrMarkov[MAXROW+1][MAXCOL+1];
0
 
LVL 8

Author Comment

by:deadite
ID: 17875267
ozo,

that worked!  The only question I have is why?  Shouldn't C array elements start at 0, so declaring an array[4] should have the elements array[0] [1] [2] [3] [4] right?
Thanks
0
Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

 
LVL 13

Expert Comment

by:marchent
ID: 17875362
>>elements array[0] [1] [2] [3] [4] right?
no, it should be
elements array[0] [1] [2] [3]

~marchent~
0
 
LVL 1

Assisted Solution

by:Mathematix
Mathematix earned 80 total points
ID: 17875485
The problems causing the memory exceptions to be raised are your conditionals and declarations. Remember that arrays are zero-indexed, so if you declare:

int MAXROW = 4;
int MAXCOL = 4;
float arrMarkov[MAXROW][MAXCOL];

you have declared a 4x4 2D array (or 'matrix' as you prefer to call it), and the first element is

arrMarkov[0][0];

and the last

arrMarkov[4][4];

A quick lesson in inequalities. I don't know how well versed you are in mathematix, but you should be aware of the following for inequalities:

< has the logical opposite >= and vice-versa.
> has the logical opposite <= and vice-versa.
= has the logical opposite != and vice-versa.

These are simple rules that are critical when evaluating logical expressions in programming. Your first error is:

for (row = 0; row <= MAXROW; row++)

From the rules above I am sure that you can already see the error, since = is not the logical opposite of <=. This means that the expression will only evaluate false at MAXROW + 1 which is two elements out of the array boundaries. In fact MAXROW + 1 will never be reached, as the expeption will be raised as soon as to try to access arrMarkov[5][n]. Why? Recall that arrays are zero-indexed so the index values are only allowed to fall in the following ranges (where 'r' is the row index and 'c' is the column index):

arrMarkov[0 <= r < MAXROW][0 <= c < MAXCOL];

That is, for your definition the index values should fall between 0 and 3 because MAXROW = 4 and MAXCOL = 4.

Your corrected for-loops should be:

for (row = 0; row < MAXROW; row++)  and
for (col = 0; col < MAXCOL; col++)

and given that you want a 5x5 matrix, you should amend your definitions of MAXCOL and MAXROW to the following:

#define MAXROW  5
#define MAXCOL 5

SOME NOTES ON PROGRAMMING PRACTICE
============================

------------------------------------------------------
The solution

for (row = 0; row < MAXROW; row++)  and
for (col = 0; col < MAXCOL; col++)

can also be expressed as

for (row = 0; row != MAXROW; row++)  and
for (col = 0; col != MAXCOL; col++)

As per my inequalies expressed earlier. Don't use the '!=' version! Why? Because '!=' is not equal to '<'. '!=' checkes against a single value, so if you are incrementing row or col by an odd value the '!=' version of the conditional will always evaluate true if both MAXCOL and MAXROW are 4. The '<' version will evaluate false when a value >= MAXROW or MAXCOL is encountered and exit the loop.

------------------------------------------------------

#define MAXROW  5
#define MAXCOL 5

This declaration is also very bad, since the preprocessor does not perform type checking. Change to:

const int MAXROW = 5;
const int MAXCOL = 5;

------------------------------------------------------

float arrMarkov[MAXROW+1][MAXCOL+1];

Avoid arithmentic as 'indexes' to arrays. Why?

1. Depending on the situation, performing arithmetic within array indices forces the compiler to create a temp variable, perform the arithmetic, then apply the temp variable's value to the index, then destroy the temp variable. This is inefficient and not necessary.

2. Array indices should always be checked before an array is indexed. Therefore if you perform arithmentic within an index you could end up with an out-of-bounds index that would avoid those horrible exceptions and hard to find bugs.

------------------------------------------------------

Change

printf("\n");

to

putchar('\n');

printf() should be used when you wish to print a string (that is, an array of type 'char' in C), and putchar() when you wish to send a single character to standard output.

------------------------------------------------------

I hope this clarifies matters. :)
0
 
LVL 8

Author Comment

by:deadite
ID: 17875783
DUH,

writing programs for 30+ hrs really does affect your mind!  I see exactly where my error was now.   Also, I had another typo up there in my explanation question... obviously there will not be a [4] element since the array is 0 indexed.  Thank you all for pointing out the obvious...
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17876758
> writing programs for 30+ hrs really does affect your mind!  I see exactly where my error was now.

Don't worry, mate. It happens. Glad you've worked it out. :)
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question