2 Dimensional array and Print out average of the Columns and Rows - c

Im still a beginner in C programming and I need a little help writing a code for my C programming class.
The prompt is: Input for this program is a two-dimensional array of floating point data located in a file named textfile94. The input array will contain 3 rows of data with each row containing 5 columns of data.
I want you to use the two-subscript method of dynamic memory
allocation.
Use malloc to create an array that holds pointers.
Each element of that array points at another array, which is the row of data.
Use malloc in a loop to create your rows.
Then you can use two subscript operators [r][c] to get at your data
to do the summing and averaging that the program calls for.
This program calls for hard-coded height and width of the 2D array,
known ahead of time (3x5, actually).
Instead of writing in the literal numbers in your code, I want you to
create a global constant variable to hold those dimensions, and use
those in your code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define int rows = 3;
#define int columns = 5;
float array[rows][columns];
int main(int argc, char* argv[]){
FILE* fin;
float x;
int i,j;
int* array;
fin = fopen("textfile94", "r");
fscanf(fin,"%f", &x);
array =(int*) malloc(rows* sizeof(int*));
for(i=0;i<rows;i++){
for(j=0;j<columns;j++)
array[i]=(int*)malloc(columns* sizeof(int));
}
printf("The Average values for the three rows are:[%f]",array[i]);
printf("The Average values for the five columns are:[%f]", array[j]);
return 0;
}
In text file: 4.33 5.33 1.11 99.00 100.00 1.0 33.3 12.5 1.1 -1000.00 22.1 11.9 2.4 8.3 8.9
The program should output:
The average values for the three rows are: 41.95 -190.42 10.32
The average values for the five columns are: 9.14 16.84 5.33 36.13 -297.7
Having Trouble getting it to do this correctly, any help would be appreciated. I don't want the answer I want to learn from this but just need some hints. Thank you.
Updated Code:
#include <stdio.h>
#include <stdlib.h>
#define ROWS 3
#define COLUMNS 5
float array[ROWS][COLUMNS];
int main(int argc, char* argv[]){
FILE* fin;
int i;
float x;
float** array;
fin = fopen("textfile94", "r");
array=(float**) malloc(ROWS*sizeof(float*));
for(i=0;i<ROWS;i++)
array[ROWS]=(float*)malloc(COLUMNS*sizeof(float));
for(j=0;j<COLUMNS;j++){
fscanf(fin,"%f",&x);
x = array[ROWS][COLUMNS];
}
printf("The Average values for the three rows are:%f", array[ROWS]);
printf("The Average values for the five columns are:%f", array[COLUMNS]);
return 0;
}

Ok, I'll see what I can add.
Defines are not written like that, and by convention should be all upper case
#define ROWS 3
#define COLUMNS 5
He wants you to dynamically allocate the array via malloc, you are now statically allocating a 2-dimensional array of floats and then you try to force arrays of ints into it. You should look up how to do multidimensional arrays with malloc.
Basically what you want is
float **array;
Now array is a pointer to pointer to float, then assign array rows number of pointers to float.
ROWS * sizeof(float*)
After that you can for each row assign array[row] with
COLUMNS * sizeof(float)
Now you have your array[ROWS][COLUMNS] structure
One approach to reading in the data in pythonesque pseudo code would be
for(row 1..3)
array[row] = malloc(...)
for(col 1..5)
fscanf(value)
array[row][col] = value
Tell me if I am being too vague, trying to give hints without giving the code.

This should get you started on how to allocate the array, assign and access values, and then free memory. Error checking is omitted for clarity. Most likely you will want verify that calloc actually returns a valid pointer.
To complete the program you will have to read the values into the array and then calculate the averages.
#include <stdlib.h>
#include <stdio.h>
const size_t rows = 3;
const size_t columns = 5;
int main(void)
{
size_t i, j;
/* allocate a two-dimensional array of zeroes */
double **array = calloc(1, rows * sizeof(double *));
for (i = 0; i < rows; ++i) {
array[i] = calloc(1, columns * sizeof(double));
}
/* print it out - replace this by reading in values */
for (i = 0; i < rows; ++i) {
for (j = 0; j < columns; ++j) {
fprintf(stdout, "%.2f", array[i][j]);
fputc(' ', stdout);
}
fprintf(stdout, "\n");
}
/* TODO loop through the array again and average the data */
/* free memory */
for (i = 0; i < rows; ++i) {
free(array[i]);
}
free(array);
return EXIT_SUCCESS;
}

Related

c - Which is the correct way to dynamically allocate multidimensional float arrays? Valgrind error

I'm implementing a K-means algorithm in C. It works well most of the time, but debugging it with Valgrind tell me that I'm doing an "Invalid read of size 8 - Invalid write of size 8 - Invalid read of size 8" using '''memcpy''' at the beginning. I think the problem isn't there, but where I assign a value to the multidimensional float array element, which memory is dynamically allocated with '''malloc''' with a for loop at some point. 'Cause Valgrind also tell "Address 0x572c380 is 0 bytes after a block of size 80 alloc'd".
I've tried to add 1 to the number of bytes that I allocate, cause I thought that maybe '''malloc''' "needed" more memory to do its job, but nothing changed. I know maybe it's a basic error, but I'm quite new to the language and at my course it wasn't explain anything so "technical". I've tried to search the answer and explanation of the error but I have only found problems with '''char''' arrays, and with those I'd understood the function '''strcpy''' can resolve the issue. What about float arrays? It's the first time a use '''memcpy'''.
Here are pieces of code that raise those Valgrind messages.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(){
FILE* fp; //used to open a .txt file to read
char buf[100];
float ** a;
char * s;
int i;
int j;
int rows = 10;
fp = fopen("data.txt", "r");
if(fp==NULL){
perror("Error at open file.");
exit(1);
}
a = (float**) malloc(rows*sizeof(float*));
for(i=0; i<rows; i++){
s = fgets(buf, 100, fp); //reading .txt file
if (s==NULL){
break;
}
a[i] = malloc(dim*sizeof(float));
a[i][0] = atof(strtok(s, ","));
for(j=1; j<dim; j++){
a[i][j] = atof(strtok(NULL,",")); //save as float value the token read from a line in file, for example, from line "1.0,2.0,3.0" as first line -> get a[0][1] = 2.0
}
}
fclose(fp);
m = (float**) malloc(rows*sizeof(float*));
for (i=0; i<rows; i++){
m[i]=malloc(dim*sizeof(float)); //not initialized
}
memcpy(m, a, rows*dim*sizeof(float));
}
Can someone also help me understand why it works but Valgrind raises these error messages?
You're first allocating an array of float*, then allocating several arrays of float so your last memcpy(m, a, rows*dim*sizeof(float)) copies an array of float* (pointers to float) to another one, but using rows * dim floats, which #SomeProgrammerDude rightfully noted. That would copy pointers, and not values.
Also, as pointed by #xing, you're allocating rows but using righe (which you didn't show). It might be a cause of problems.
I would suggest allocating the whole array at once on the first row, then having all other rows pointing to adequate rows:
a = malloc(rows * sizeof(float*));
a[0] = malloc(dim * rows * sizeof(float)); // Allocate the whole matrix on row #0
for (i = 1; i < rows; i++) {
a[i] = a[0] + i * dim; // sizeof(float) automatically taken into account as float* pointer arithmetics
}
...
m = malloc(rows * sizeof(float*));
m[0] = malloc(dim * rows * sizeof(float));
memcpy(m[0], a[0], dim * rows * sizeof(float));
(add NULL checks of course)

fread'ing a binary file into a dynamically allocated C array

Just a quick comment to start: While there are similar threads to this one, I haven't quite been able to find the solution I'm looking for. My problem is the following:
I have 2D arrays of doulbes saved to binary files and I would like to read the binary files (using C code) into a 2D array. Additionally, I need to allocate the memory dynamically as the shape of the arrays will be changing in my application. To get started, I tried the following code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
int N = 10; //number of rows of 2D array
int M = 20; //number of columns
/* first allocate the array */
double **data;
data = (double **)malloc(N*sizeof(double *));
for(unsigned int i=0; i < N; i++) {
data[i] = (double *)malloc(sizeof(double)*M);
}
FILE *ptr;
ptr = fopen("random_real_matrix.dat", "rb");
fread(data, sizeof(data), 1, ptr);
for(unsigned int i=0; i<10;i++){
for(unsigned int j=0; j<20;j++){
fprintf(stderr, "m[%d][%d] = %f\n ", i, j, data[i][j]);
}
}
}
Unfortunately, this code segfaults. I checked to see if I can set the array entries like
d[0][0] = 235;
and that works fine.
Assuming this approach can be fixed, I'm also interested to know if it could be extended to read to an array of double complex's.
Any advice would be greatly appreciated!
Your fread statement is incorrect. It's a common beginner mistake to think that sizeof gets the size of a dynamically allocated array. It doesn't. In this case it just returns the size of a double **. You will need to read in each double in the file and put that into the correct spot in the array.
for (int ii = 0; ii < N; ++ii)
{
for (int jj = 0; jj < M; ++jj)
{
fread(data[ii][jj], sizeof(double), 1, ptr);
// Be sure to check status of fread
}
}
You can do this with a single for loop (or a single fread) but this is probably clearer to read.
Because you allocated each row separately, you can't read into the entire array at once. You need to do it row by row.
for (int i = 0; i < N; i++) {
fread(data[i], sizeof(double), M, ptr);
}

Reading 2d array from binary file and return the pointer this array (in C)

I am trying to write a function that returns the pointer of 2d array read from a binary file. Although I compile without error there is always a segmentation fault, when I try to print one of the elements of the array. Here my code:
double ** readArray(int rows, int cols)
{
int i;
double **myArray=malloc(rows*sizeof(double*));
if (myArray){
for (i=0; i < rows; i++)
{
myArray[i]=malloc(cols*sizeof(double));
}
}
FILE *data;
data=fopen("matrix.bin", "rb");
fread(myArray,sizeof(double),rows*cols,data);
return myArray;
}
int main ()
{
int cols = 7;
int rows = 15;
double **myArray=readArray(rows, cols);
printf("%f\n", myArray[1][0]);
return 0;
}
The problem is that there is no 2D array in your code. The pointer-to-pointer look-up table thing is not a 2D array. It is [rows] number of segments scattered all over the heap, at random places. It is therefore also needlessly slow.
Also, you should keep memory allocation and algorithms separated.
Do something like this instead:
#include <stdio.h>
#include <stdlib.h>
void* allocArray (int rows, int cols)
{
return malloc( sizeof(double[rows][cols]) ); // allocate 1 2D-array
}
void readArray (int rows, int cols, double array[rows][cols])
{
FILE *data;
data=fopen("matrix.bin", "rb");
fread(array, sizeof(double[rows][cols]), 1, data); // read 1 2D-array
}
int main ()
{
int cols = 7;
int rows = 15;
double (*myArray)[cols] = allocArray(rows, cols);
readArray(rows, cols, myArray);
printf("%f\n", myArray[1][0]);
free(myArray); // free 1 2D-array
return 0;
}
The reason for the peculiar declaration double (*myArray)[cols] instead of the more logical double (*myArray)[rows][cols], is that we want to avoid the inconvenient array pointer de-referencing syntax. (*myArray)[1][0] is not easy to read. So instead of declaring an array pointer to a 2D array, declare an array pointer to a 1D array, then use pointer indexing on that array pointer. For any pointer, any_pointer[n] gives pointed-at item number n. Array pointers are no difference, so you get 1D array number n.
Your fread() call is overwriting all those pointers you painfully set up.
You need to read a single row at a time, and use the set-up pointer to store to:
for(size_t i = 0; i < rows; ++i)
fread(myArray[i], cols * sizeof *myArray[i], data);
Also, when doing I/O and memory allocation you should check the return values too, of course.

How to malloc a 2d jagged array using a pointer passed by reference to a function in C

I have a 2D jagged array declared in my main() block. This is to be passed to a function to have memory allocated to it. The following is the most reduced case which compiles but crashes when it runs. Where am I going wrong?
#include <stdio.h>
#include <stdlib.h>
void alloc2d(double ***p);
int main () {
double **data;
alloc2d(&data);
printf("Before assign to data\n");
data[0][0] = 0.1;
printf("After assign to data\n");
free(data);
}
void alloc2d(double ***p) {
int i, n, m;
// Get some dynamically assigned sizes
printf("Enter size: ");
scanf("%d %d", &n, &m);
// Now allocate
*p = malloc(n * sizeof(double*));
for (i = 0; i < n; i++) {
*p[i] = malloc(m * sizeof(double));
}
printf("End of alloc2d\n");
}
This reads the values but crashes when I enter low numbers (i.e. '1 1') but crashes when I enter high numbers (i.e. '10 10').
You made a very simple syntax error
*p[i] = (double*)malloc(m * sizeof(double));
should really be
(*p)[i] = (double*)malloc(m * sizeof(double));
This is because in C, [] operator has higher precedence than *.
So when you type *p[i],
it is translated into **(p + i).
This means: you are asking the compiler to calculate the address by offsetting the address of p by i * sizeof(double**), which is clearly not what you actually want.
So, in order to force the compiler to dereference p first, simply surroud *p with brackets.
Operator precedence is the answer. *p[i] is equivalent to *(p[i]). This makes you access memory that lies right after the data pointer, which will either corrupt some other variables on the stack, or crash completely.
You were looking for (*p)[i], which will be the i-th entry in the newly allocated array.
What your alloc2d() allocates is not really a 2D array, but:
1 1D n-long array of pointers to double
n 1D m-long arrays of doubles
Multi-dimensional arrays in C are only possible, if all but the last of the dimensions are known at compile-time:
double a[5][11];
Maybe, this program can help you understand... Note, how COLUMNS is a compile-time constant, even if rows is a run-time variable:
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <err.h>
typedef double myrow_t[11]; /* 11 columns */
#define COLUMNS (sizeof(myrow_t)/sizeof(double))
static unsigned
alloc2d(myrow_t **pd)
{
unsigned int rows;
printf("Enter the number of rows: ");
while (scanf("%u", &rows) != 1)
printf("\ninvalid input, please, try again: ");
*pd = malloc(rows * sizeof(**pd));
if (*pd == NULL)
err(EX_TEMPFAIL, "Out of memory");
return rows;
}
int
main()
{
myrow_t *d;
unsigned int row, column, rows;
rows = alloc2d(&d);
for (row = 0; row < rows; row++)
for (column = 0; column < COLUMNS; column++)
d[row][column] = row * column;
for (row = 0; row < rows; row++) {
printf("Row %3d:\t", row);
for (column = 0; column < COLUMNS; column++)
printf("%.0f\t", d[row][column]);
puts("");
}
free(d);
return 0;
}

2d array rows/columns length C

I need to declare a 2d array to represent the size of chess-board. However, I'm having a trouble understanding how would I actually calculate the width and the length of the board.
I would like to know how could I calculate size of the rows and columns of my 2d array
Say, int boardSize[5][5]?
int main()
{
int boardSize[5][5];
int boardWidth=?
int boardHeight =?
createBoard(boardWidth, boardHeight);
}
int createBoard(int width, int height)
{
// code that actually creates board //
}
Sorry, for not being specific in the begging. So, here I need to calculate boardwidth and boardheight variables? How do I do that from the declared array above. Thank you!
boardSize[0] gives you the first row of the matrix, boardSize[0][0] the first of its elements. So the quantities you are looking for are sizeof boardSize/ sizeof boardSize[0] and sizeof boardSize[0]/ sizeof boardSize[0][0].
BTW: use size_t as a type for sizes, not int.
If you say
int boardSize[5][5];
that gives you a 2D array of integers, 5 by 5 in size. So it will have 5 rows of 5 columns each, for a total of 25 integers.
printf("Size of the board in bytes %d\n", sizeof(boardSize));
printf("Size of column size in bytes %d\n", 5*sizeof(int));
printf("Size of row in bytes %d\n", 5*sizeof(int));
If you want leave the board as statically allocated the declare it as global like,
static int board[5][5];
Then traverse it in your "createBoard" method(I hate Hungarian notations) for correct initialization :
for(i = 0; i < hight; i++)
for(j = 0;j< width; j++)
board[i][j] = <initialization stuff>
or you can dynamically allocate it in your createBoard() method. In that case do not declare as local variable for main.
int * createBoard(int hight, int width){
int * board;
if(board = malloc(sizeof(int) * hight * width))
return board;
return NULL;
}
in main() you can do something like this:
int * board = createBoard(5,5);
if(!board)
printf("Allocation failure \n");
exit(EXIT_FAILURE);
This is easily fixed with the removal of all mysterious magic numbers from your code.
#define BOARD_WIDTH 8
#define BOARD_HEIGHT 8
square_t board [BOARD_WIDTH][BOARD_HEIGHT];
createBoard (board, BOARD_WIDTH, BOARD_HEIGHT);
void createBoard (square_t* board, int boardWidth, int boardHeight)
{
}

Resources