Glitch initialising matrix in C - c

I am trying to create a matrix in C in order to solve the LaPlacian
However, this is going wrong. I have located the problem at the initialisation stage of the matrix. Every time the program is run, it places a seemingly random value in one element. This number changes each time suggesting an instability in the code, and happens if the matrix is made to be greater than 9x9.
Why could this be happening?
Thanks
The code I am using to show the matrix is:
// create matrix
double mat[meshno][meshno] = { {0} }; // x direction defined by i, y by j
//variables
int i, j, k;
//print initial matrix
for (i=0;i<=meshno;i++)
{
for(j=0;j<= meshno;j++)
{
printf("%f ", mat[i][j]);
}
printf("\n");
}

You are looking at an element past the end of each array.
Your for loops should use < and not <=:
for (i = 0; i < meshno; ++i)
{
for(j = 0; j < meshno; ++j)
{

Change to
for (i=0; i< meshno;i++)
{
for(j=0; j< meshno;j++)
{

Related

Storing matrix data from a text file in a multidimensional array in c

So, I'll preface this by saying I'm fairly new to pointers and dynamic allocation. Currently I am trying to store a file that contains a 3x3 matrix of ints into a 2d array. I've tried debugging my code and what I notice is that it reads my first 2 values, but than begins to generate random garbage into my 2d array. I assume that I am storing my ints incorrectly and there is a flaw in my logic, but as I keep trying to think about it, I can't seem to find where it could be incorrect as they are moving from [0][0], [0][1], etc.
Here is my code for reference. Thanks, I'd appreciate just some guidance on how I can troubleshoot this problem for this specific case and future issues.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fpM1;
fpM1 = fopen("m1.txt", "r");
int i, j, row1 = 2, col1 = 2;
int* ptrM1 = (int* )malloc(9 * sizeof(int));
if (fpM1 != NULL) {
for (i = 0; i < row1; i++) {
for (j = 0; j < col1; j++) {
fscanf(fpM1, "%d", ((ptrM1 + i) + j));
}
}
for (i = 0; i < row1; i++)
for (j = 0; j < col1; j++) {
{
printf(" %d", *((ptrM1 + i) + j));
}
}
}
free(ptrM1);
fclose(fpM1);
return 0;
}
Your for loops end too fast. You should use <= instead of <. After that, everything seems to work perfectly.
Maybe you should consider adding new line in outer for loop during printing array. It will help with clarity:
for (i = 0; i < row1; i++) {
for (j = 0; j < col1; j++) {
printf(" %d", *(ptrM1 + i));
}
printf("\n");
}
Also you don't need those double brackets before first printf statement. In C you can put many scopes without context, but you shouldn't do that without reason.
EDIT: It actually doesn't work. Reading from file should be done this way:
fscanf(fpM1, "%d", ptrM1 + (i * (col1 + 1) + j));
and printing:
printf(" %d", ptrM1[i * (col1 + 1) + j]);

Why doesn't work the matrix with 5,3 but 3,5?

I've written this code, but i don't know why it fails with the 5 3 input.
When I give 3 5 it works fine. In every case, if the second number is bigger, It works, but why? I've already tried it with malloc. I'm using Windows 7, Code Blocks 10.05
#include<stdio.h>
#include<stdlib.h>
int main()
{
int **matr;
int row, col, i, j;
scanf("%d", &row); //number of rows
scanf("%d", &col); //number of cols
matr = calloc(col, sizeof(int*)); //creating cols
for(i = 0; i < col; i++)
{
matr[i] = calloc(row, sizeof(int)); //in every col i create an array with the size of row
}
for(j = 0; j < row; j++)
{
for(i = 0; i < col; i++)
{
matr[j][i] = 10; //fill the matrix with number 10
}
}
printf("Matrix is ready\n");
for(j = 0; j < row; j++) //printing the matrix
{
for(i = 0; i < col; i++)
{
printf("%d ", matr[j][i]);
}
printf("\n");
}
return 0;
}
Try matr[i][j] instead of matr[j][i].
In other words, carefully check order of indexes and their ranges.
You correctly allocated a matrix of size [col][row]. And then you access it as if it is a matrix of size [row][col]. No wonder it crashes.
First decide what index interface you want to use - [col][row] or [row][col] - and then either change the allocation of change the access so that they match.
In the calloc, you inverted row and column, so your 2d array size is mixed up.
I have tried it, it worked. So the first memory allocation gives the rows. e.g.
matrix[this part will be given with the first allocation] [the second in the for]
Thanks a lot, I succeded in writing a source code that multiplies matrices :)
I'll vote as soon as i can

Was told my C program was "hard coded" and I don't understand why

I turned in my assignment to my online C programming class and was docked huge due to the fact that my program was "hard coded, and I can't see how it would be considered "hard coded" as I ask for user input. The following was my code:
#include <stdio.h>
#include <stdlib.h>
#define IMAX 3
#define JMAX 4
int main()
{
float a[IMAX][JMAX];
float avgrow[5];
float avgcol[5];
int i,j;
char c;
printf ("This program will allow you to enter numbers for 3 rows and 4 columns from left to right then filling down, and take the averages of the rows and columns and list them next to the row and under the columns. You may use decimals but only 2 will display in the results. Press enter!\n");
scanf ("%c",&c);
printf("Enter 12 numbers here for your rows and columns:\n");
for(i = 0; i < IMAX; i++)
{
for(j = 0; j < JMAX; j++)
{
scanf("%f",&a[i][j]);
}
}
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}
printf(" Column1 Column2 Column3 Column4 Row Average\n\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[0][0],a[0][1],a[0][2],a[0][3],avgrow[0]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[1][0],a[1][1],a[1][2],a[1][3],avgrow[1]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[2][0],a[2][1],a[2][2],a[2][3],avgrow[2]);
printf("\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t\n",avgcol[0],avgcol[1],avgcol[2],avgcol[3]);
return 0;
}
All it was supposed to do was make a 2-d array with 3 rows and 4 columns, then take the average of the rows and display that next to to the row in a table. Than take the average of the columns and display them beneath the columns in the table.
This was his comments on my assignment "Well, you got the correct answers, but when dealing with a 2-D array, you should use nested for loops. Not one for loop and then a lot of "hard coding" values into the program."
Any help deciphering this would be appreciated as I though I was finally understanding programming until this.
First of all it's not meaningful to talk about a program being hard coded or not. Rather one would talk about specific values being hard coded. What this means is that you wrote their values directly into the code rather than putting them in a constant or variable that can easily be changed.
In this case the values you hard-coded are the number of rows and the number of columns. You do have constants for these, but you don't use them consistently. That is if you changed your constants to turn the array into a 5x5 array, your code would now break because parts of the code would still act like it is an 3x4 array.
Specifically there are two loops in your code where you're accessing the indices [0][0] through [2][3] by spelling out each index in that range specifically rather than using a loop. This means that if you change IMAX and JMAX, it will still use those same indices, which aren't correct any more.
So your array indices are hard-coded and changing the array dimensions breaks your program.
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}
Notice the copying/pasting of nearly identical code? That's often a sign of hardcoding -- the presence of constants in the code's text or structure. How do you change the 3 and the 4? They're "hard" -- built into the code.
The proof it's a problem -- you have:
#define IMAX 3
#define JMAX 4
But if you actually change those, the code will break. Look at this line of code:
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
That's an average if, and only if, JMAX is 4. The code was build with the understanding that JMAX had to be 4 -- JMAX was "hard coded" to 4.
Looking at the following code:
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
This code assumes that a always has 3 rows and 4 columns, regardless of how a was actually declared. If you changed JMAX to 2, for example, then your code above would break because a would have dimension 3x2, and you'd be attempting to access elements outside of the array bounds.
What your instructor was looking for was something along these lines:
for(j = 0; j < JMAX; j++)
{
float sum = 0.0;
for (i = 0; i < IMAX; i++ )
{
sum += a[i][j];
}
avgrow[j] = sum/JMAX;
}
This code makes no assumptions about the dimensions of a beyond what is specified by IMAX and JMAX.
Note also that your declarations for avgrow and avgcol are hard-coded to 5, when they should also be based on IMAX and JMAX:
float avgrow[IMAX];
float avgcol[JMAX];
float avgrow[5];
float avgcol[5];
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[0][0],a[0][1],a[0][2],a[0][3],avgrow[0]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[1][0],a[1][1],a[1][2],a[1][3],avgrow[1]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[2][0],a[2][1],a[2][2],a[2][3],avgrow[2]);
printf("\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t\n",avgcol[0],avgcol[1],avgcol[2],avgcol[3]);
THESE ALL STEPS YOU HAVE TAKEN ARE HARD CODING AS YOU ARE SPECIFICALLY MENTIONING THE INDICES IF SUPOSE the value imax and jmax changes then you have to manually change/add avgcol[index] in taking averages as well as in output...
Your programm should be independent of it it should only depend on the value of i max and jamx
for a reference you can view a sample of your code in which i have removed hardcoding
http://ideone.com/mXymKS
Although this code could be simplied to a great extent...
You have used explicit integer values for the array indices of avgrow and avgcol. To avoid hard-coding, try using a loop with an integer variable as index, e.g.,
for(int k=0; k<4; ++k)
and then assign values to avgrow[k].
Your professor expected you to be able to modify the number of line and columns in your program easily. The disadvantage of the program you wrote is that a modification of one of those two parameters require you to change the whole program. You can achieve more flexibility for instance like this:
#include <stdio.h>
#include <stdlib.h>
#define IMAX 3
#define JMAX 4
int main()
{
float a[IMAX][JMAX];
float avgrow[IMAX] = {0};
float avgcol[JMAX] = {0};
printf ("This program will allow you to enter numbers for %d rows"
"and %d columns from left to right then filling down, and"
" take the averages of the rows and columns and list them"
" next to the row and under the columns. You may use "
"decimals but only 2 will display in the results. Press"
" enter!\n", IMAX, JMAX);
char c;
scanf ("%c",&c);
printf("Enter %d numbers here for your rows and columns:\n", IMAX * JMAX);
for(int i = 0; i < IMAX; i++) {
for(int j = 0; j < JMAX; j++) {
scanf("%f",&a[i][j]);
}
}
for(int i = 0; i < IMAX; i++) {
for(int j = 0; j < JMAX; j++) {
avgrow[i] += a[i][j];
}
avgrow[i] /= JMAX;
}
for(int j = 0; j < JMAX; j++) {
for(int i = 0; i < IMAX; i++) {
avgcol[j] += a[i][j];
}
avgcol[j] /= IMAX;
}
for(int i = 0; i < IMAX; i++) {
printf("Column%d\t", i);
}
printf("Row-Average\n\n");
for(int j = 0; j < JMAX; j++) {
for (int i = 0; i < IMAX; i++) {
printf("%8.2f\t", a[i][j]);
}
printf("%8.2f\n", avgrow[j]);
}
for(int i = 0; i < IMAX; i++) {
printf("%8.2f\t", avgcol[i]);
}
return 0;
}
In addition to the rich answers already exist, I'd like to point out something about acquiring data and computing averages without much repetitions :
So define your average arrays like this :
float avgrow[IMAX] ={0};
float avgcol[JMAX] ={0};
Then in the same loop where you scanf user's entries you can simultaneously compute averages like this:
printf("Enter %d numbers here for your rows and columns:\n", IMAX*JMAX);
for(i = 0; i < IMAX; i++)
{
for(j = 0; j < JMAX; j++)
{
scanf("%f",&a[i][j]);
avgrow[i] += a[i][j]/JMAX;
avgcol[j] += a[i][j]/IMAX;
}
}
Next step is just to print out everything, and let it be automated too :)
for(i=1; i<= JMAX; i++) printf("Column%d\t\t", i);
printf("Row Average\n");
for(i=0; i<IMAX; i++)
{
for(j=0; j<JMAX; j++)
{
printf("%8.2f\t", a[i][j]);
}
printf("%8.2f\n", avgrow[i]);
}
for(i=0; i<JMAX; i++)
printf("%8.2f\t", avgcol[i]);
By the END
you have a code that computes row and col averages for any sizes. i.e. try changing IMAX or JMAX

Image flipping incorrectly...Why?

I am trying to flip my image on a Y Axis, and it does flip, but it leaves odd spaces in the middle and on the right side, it wont flip the entire image perfectly, I am limiting the images to 450 by 450 and a P3...Anyone have any ideas, because my algorithm is correct
for(j=0; j < imgur.width/2; j++)
{
for(i=0; i < imgur.height; i++)
{
temp.red = imgur.image[i][j].red;
imgur.image[i][j].red = imgur.image[i][imgur.height-j-1].red;
imgur.image[i][imgur.height-j-1].red = temp.red;
temp.green = imgur.image[i][j].green;
imgur.image[i][j].green = imgur.image[i][imgur.height-j-1].green;
imgur.image[i][imgur.height-j-1].green = temp.green;
temp.blue = imgur.image[i][j].blue;
imgur.image[i][j].blue = imgur.image[i][imgur.height-j-1].blue;
imgur.image[i][imgur.height-j-1].blue = temp.blue;
}
}
Here's my algorithm... Before that I am printing out the P3, the comment, the width and height, and the maxColor. I am using two structs to get the data and reading in a file from the terminal...
Here's how I'm printing out the data. Anyone have any ideas?
for(i=imgur.height-1; i >= 0; i--)
{
for(j=0; j < imgur.width; j++)
{
printf("%i\n", imgur.image[i][j].red);
printf("%i\n", imgur.image[i][j].green);
printf("%i\n", imgur.image[i][j].blue);
}
}
my symmetric detector is confused by (in the upper part)
for(j=0; j < imgur.width/2; j++) {
for(i=0; i < imgur.height; i++) {
and (in the lower part)
for(i=imgur.height-1; i >= 0; i--) {
for(j=0; j < imgur.width; j++) {
You have made a little typo mistake in the flip algorithm: as you flip upside-down, you have to scan all lines entirely and half of the height of the image, not the inverse.
for(j=0; j < imgur.width; j++)
{
for(i=0; i < imgur.height/2; i++)
{
//code of your loop, removed for compactness
}
}
EDIT
In fact, for left-right swapping, you have also inverted the complement of index j. j is along the X-axis, belonging the range 0:width-1, so the complement is width-1-j.
I have coded a version of this algorithm a long time ago, it was like that:
for (i=0; i!=h; i++) {
for (j=0; j!=w/2; j++) {
temp = src[i][w-1-j];
dst[i][w-1-j] = src[i][j];
dst[i][j] = temp;
}
}
I think it works fine (As you are working with a pixel struct, it is perfectly correct to swap the whole pixel like this).

For loop within a for loop in c

For some reason my outer for loop does not seem to be doing anything, I have checked all the paranthesis and everything looks ok but it is still not looping.
With this program I want to sum 50 random numbers (the numbers can either be 1 or -1...it's for a computational physics problem) and print the magnitude, which the program does. BUT I want to go further and do this 10 times, and calculate the average magnitude.
I know what I need to do I'm just having a problem with this loop.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h> //Neeed this to seed the random generator with time, or else it will always generate the same numbers.
//This is a program to calculate the magnitude of the displacement of a particle after random collisions.
#define RAND_MAX 1
int main()
{
//using ints because the particle can only move one unit on x-axis at a time.
int i, x, displacement, sum = 0, avg;
int total_disp=0, mag_disp;
srand(time(NULL));
//Each collision causes the particle to advance or retreat by one unit on the x axis.
for(i=0; i<10; i++)
{
for (i=0; i<50; i++) //for 50 collisions
{
x = rand() % 2; //generates random numbers between 0 and 1.
if (x==0) //if x is 0 then it was a displacement in the minus x direction
{
displacement = -1;
}
else { //if x is 1 it is a displacement in the minus x direction
displacement = 1;
}
printf("the disp is : %d\n", displacement);
total_disp = total_disp + displacement; //sum the displacements
}
if (total_disp < 0) {
mag_disp = total_disp * -1;
}
else{ mag_disp = total_disp; }
printf("The total displacement is: %d\n", mag_disp);
sum = sum + mag_disp; //sum of the displacement magnitudes, there should be ten of them in this case
avg = sum / i; //average displacement is the sum of all the magnitudes divded by the number of times this is performed.
printf("The average displacement for i = %d particles is: %d", i, avg);
}
return 0;
}
You cannot use the same iteration variable in both loops.
for(i=0; i<10; i++)
for (i=0; i<50; i++)
increments i to 50 in the first iteration of the outer loop.
for(i=0; i<10; i++)
for (j=0; j<50; j++)
will work.
You're using the same variable i for both loops. You should use different variables.
...
for(j=0; j<10; j++)
{
for (i=0; i<50; i++) //for 50 collisions
{
...
Use different loop variables for the inner and outer loops.
When the first iteration of the inner loop is done i == 50, so the outer loop is also done.
Try this:
for(int i=0; i<10; i++)
{
for(int j=0; j<50; j++)
{ ... }
}
And change your variables accordingly.
Dennis is right.
in ANSI C, i and j must be declared in the begining of the function :
int main()
{
int i,j;
...//instructions
for( i=0; i<10; i++)
{
for( j=0; j<50; j++)
{ ... }
}

Resources