Filling C array with pointers - c

The following function is supposed to fill a two dimensional array with floats increasing by 0.5
void MatrixFill(float *pf, float x, int rows, int columns, FILE *fp) {
int i, j;
printf ("\n***\tBegin MatrixFill\t***\n\n");
fprintf (fp, "\n***\tBegin MatrixFill\t***\n\n");
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
*(pf + i + columns ) = x;
x += 0.5;
}
}
printf ("\n***\tEnd MatrixFill\t***\n\n");
fprintf (fp, "\n***\tEnd MatrixFill\t***\n\n");
}
However, I'm not sure what goes in my "filling statement." (*(pf+stuff)=x;)
Any help with pointers/ array filling would be great.
Thanks!

this is were you got the mess: (pf + i + columns ) = x it should be: *(pf + i + j * rows)
Why is that?
First, you must see that each row passes through all the columns:
col1|col2|col3
----+----+----
row1 | |
----+----+----
Now, you see if you want to get to row number x, you must pass through all the columns x times!
Generally Speaking
in each 2D array arr[COLS][ROWS] where COLS and ROWS are the total numbers of columns and rows consequently, arr[i][j] = arr[i + j * COLS] = arr[j + i * ROWS]

Related

Two-dimensional dynamic array pointer access

p = (int *)malloc(m * n * sizeof(int));
If I use p as a two-dimensional dynamic array, how do I access the elements inside?
If you can rely on your C implementation to support variable-length arrays (an optional feature), then a pretty good way would be to declare p as a pointer to (variable-length) array instead of a pointer to int:
int (*p)[n] = malloc(m * sizeof(*p)); // m rows, n columns
Then you access elements using ordinary double indexes, just as if you had declared an ordinary 2D array:
p[0][0] = 1;
p[m-1][n-1] = 42;
int q = p[2][1];
Most widely used C implementations do support VLAs, but Microsoft's is a notable exception.
I'd personally prefer using wohlstad's method, but you could also variably-modified types, which are an optional feature of C11, but will probably be mandated in C2x:
int (*p)[m] = malloc(n * sizeof *p);
This can now be used just like a normal 2d array with automatic storage duration.
int n = 12, m = 9;
int (*p)[m] = malloc(n * sizeof *p);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
p[i][j] = i * m + j;
printf("%d\n", p[4][2]);
free(p);
I'll assume m is the number of columns, and n the number of rows (you can use n instead of m in my answer if it's the opposite).
In order to access the 2D array, you need 2 indices - let's call them x and y:
x index will be in the range 0 .. m-1, and
y index will be in the range 0 .. n-1
You can calculate the index for your p array in the following way:
int p_idx = y * m + x
Then you can access your arrays element e.g. this way:
p[p_idx] = 111; // set an element value
int a = p[p_idx]; // get an element value
You can't use p as a two-dimensional array. It's a single integer pointer. Two-dimensional (dynamically allocated) implies nested pointers. However, you can represent a two-dimensional array in a "flattened" form. Here's some code that might offer a helpful explanation:
#include <stdio.h>
#include <stdlib.h>
int main(){
// Populating a 10x5 matrix
int m = 10;
int n = 5;
int* p = (int*) malloc(m*n*sizeof(int));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// Each row has n elements; to get the
// "flattened" index, treating the MxN
// matrix as row-major ordered (reading
// left-to-right, and THEN down the rows):
int flattened_index = (i * n) + j;
// E.g., populate with multiplication table data
p[flattened_index] = (i + 1) * (j + 1);
printf("%d\t", p[flattened_index]);
}
printf("\n");
}
// Inversely, to convert a flattened index to a
// row and column, you have to use modulus
// arithmetic
int flattened_index = 21;
int row = flattened_index / n; // Rounded-down integer division
int column = flattened_index % n; // Remainder after division
printf("%d * %d = %d\n", row + 1, column + 1, p[flattened_index]);
return 0;
}
This outputs:
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25
6 12 18 24 30
7 14 21 28 35
8 16 24 32 40
9 18 27 36 45
10 20 30 40 50
5 * 2 = 10
You are actually creating a single-dimensional array. But still, we can use it to hold a matrix considering the fact in C a multidimensional array, e.g int mat[m][n], is stored in contiguous memory itself.
#include <iostream>
int main()
{
int m, n;
std::cin >> m >> n;
int* mat_ptr = (int*)malloc(m * n * sizeof(int));
if (mat_ptr)
{
for (int row = 0; row < m; ++row)
{
for (int col = 0; col < n; ++col)
{
*(mat_ptr + ((row * n) + col)) = (row * n) + col;
}
}
for (int row = 0; row < m; ++row)
{
for (int col = 0; col < n; ++col)
{
std::cout << *(mat_ptr + ((row * n) + col)) << " ";
}
std::cout << std::endl;
}
}
return 0;
}

Integrating dynamic programming into recursive solution

I am trying to apply dynamic programming to the following problem:
"A robot is located in the top-left corner of an m x n grid. The robot can only move down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid. How many unique paths are there?"
I have a recursive solution to this which I think works fine. However, it is slow:
int uniquePaths(int m, int n)
{
if (m==1 || n==1)
{
return 1;
}
else
{
return (uniquePaths(m,n-1)+uniquePaths(m-1,n));
}
}
I can see that it would be useful if we were able to save the outputs of the uniquePath calls since many will be done more than once. One idea I have on how to achieve this is to create an m x n array and store then outputs in there. However, this would mean I would need to input the array into my recursive function and I think for this problem I am only allowed to input two integers. Is there a simple way to apply this?
You don't need to input the array as a function argument. It can be a local variable.
The naive way: using a recursive function
If you really want to use a recursive function, you can declare the array in uniquePaths, then call another function which will use the array and do the calculations.
int uniquePaths_helper(int *grid, int m, int n, int i, int j);
int uniquePaths(int m, int n)
{
int *grid = malloc(m * n * sizeof(int));
int k;
for (k = 0; k < m * n; ++k)
{
grid[k] = 0;
}
return uniquePaths_helper(grid, 0, 0, m, n);
}
int uniquePaths_helper(int *grid, int m, int n, int i, int j)
{
if (grid[i * m + j] == 0)
{
if (i == n - 1 || j == n - 1)
{
grid[i * m + j] = 1;
}
else
{
grid[i * m + j] = (
uniquePaths_helper(grid,m,n, i+1, j)
+ uniquePaths_helper(grid,m,n, i, j+1)
);
}
}
return grid[i * m + j];
}
Being smarter: filling the array in the correct order
In the previous solution there was a lot of overhead because we had to initialise the array with default values, then at every recursive call we need to check whether the value has already been stored in the array or needs to be calculated.
You can shortcut all that. Fill the array directly using your formula on the cells of grid rather than on the arguments of recursive calls.
The formula is: grid[i * m + j] == grid[(i+1) * m + j] + grid[i * m + j+1].
The only tricky part is finding out in which order to fill the array, so that this formula can be written as a simple assignment, replacing == with =.
Since the value in a cell only depends on values with higher i and j indices, we can simply fill the array backwards:
int uniquePaths(int m, int n)
{
int *grid = malloc(m * n * sizeof(int));
int i,j;
for (int i = 0; i < n; ++i)
grid[i * m + m-1] = 1;
for (int j = 0; j < m; ++j)
grid[(n-1) * m + j] = 1;
for (i = n - 2; i >= 0; --i)
{
for (j = m - 2; j >= 0; --j)
{
grid[i * m + j] = grid[(i+1) * m + j] + grid[i * m + j+1];
}
}
return grid[0];
}

Cannot print out the values of a dynamic 2D array of structs

This program is supposed to ask the user for two values, then generate and print a table using the two values as the number of rows and columns respectively. Each cell of the table has two values, denoted as cellX and cellY. The x-value and y-value of each cell of the table is 1 and 2 respectively.
So in short, it's a dynamic 2D array of structs. The problem is, the program seems to be skipping the last for loop, so it's not printing the contents of the array of structs. No errors were generated.
#include <stdio.h>
#include <stdlib.h>
typedef struct // one cell of a table holding two int values
{
int *cellX;
int *cellY;
} Table;
int main()
{
char dump;
int row, col, y, x;
printf("Enter number of rows and columns (r,c): ");
scanf("%d%c%d", &row, &dump, &col);
Table **grid;
grid = (Table **)malloc(row * col * sizeof(Table));
for (y = 0; y < row; y++) // assigns values to the table
{
for (x = 0; x < col; x++)
{
*grid[x][y].cellX = 1; // all x-values will be 1
*grid[x][y].cellY = 2; // all y-values will be 2
}
}
for (y = 0; y < row; y++) // displays the table
{
for (x = 0; x < col; x++)
{
printf("%d, %d\t", *grid[x][y].cellX, *grid[x][y].cellY);
}
}
free(grid);
return 0;
}
grid = (Table **)malloc(row * col * sizeof(Table));
This is not how you allocate a 2D array, Table** is an array of pointers (Table*) to an array of Table, so you have to allocate all those separate sub-arrays.
Table **grid = malloc(sizeof(*grid) * row);
for (int y = 0; y < row; ++y)
grid[y] = malloc(sizeof(*grid[0]) * col);
And then remember to free all those arrays as well.
In many cases this is not really wanted, so you can make a 1D array and then index it as-if 2D. For example with array[y * width + x].
Table *grid = malloc(sizeof(*grid) * row * col);
for (y = 0; y < row; y++) // assigns values to the table
{
for (x = 0; x < col; x++)
{
grid[y * col + x].cellX = 1; // all x-values will be 1
grid[y * col + x].cellY = 2; // all y-values will be 2
}
}
Also your struct contains pointers, but I don't really see why, and you never allocated them. Just store values.
typedef struct
{
int cellX;
int cellY;
} Table;

C - stack smashing detected

I need to implement a pretty easy in-place LU-decomposition of matrix A. I'm using Gaussian elimination and I want to test it with a 3x3 matrix. The problem is, I keep getting stack smashing error and I don't have any idea why. I don't see any problems in my code, which could do this. Do you have any idea?
The problem is probably in the Factorization block.
###My code:###
#include <stdio.h>
int main() {
int n = 3; // matrix size
int A[3][3] = {
{1, 4, 7},
{2, 5, 8},
{3, 6, 10}
};
printf("Matrix A:\n");
for( int i=0; i < n; i++ ) {
for( int j=0; j < n; j++ ) {
printf("%d ", A[i][j]);
if ( j % 2 == 0 && j != 0 ) {
printf("\n");
}
}
}
// FACTORIZATION
int k;
int rows;
for( k = 0; k < n; k++ ) {
rows = k + k+1;
A[rows][k] = A[rows][k]/A[k][k];
A[rows][rows] = A[rows][rows] - A[rows][k] * A[k][rows];
printf("k: %d\n", k);
}
printf("Matrix after decomp:\n");
for( int i=0; i < n; i++ ) {
for( int j=0; j < n; j++ ) {
printf("%d ", A[i][j]);
if ( j % 3 == 0 && j != 0 ) {
printf("\n");
}
}
}
return 0;
}
Your error is most likely here:
rows = k + k+1;
A[rows][k] = A[rows][k]/A[k][k];
A[rows][rows] = A[rows][rows] - A[rows][k] * A[k][rows];
This means that rows goes through the values 1, 3, 5; and is then used to access an array with only three elements. That would, indeed, overflow, as the only valid offset among those is 1.
EDIT: Looking at your Matlab code, it is doing something completely different, as rows = k + 1:n sets rows to a small vector, which it then uses the splice the matrix, something C does not support as a primitive. You would need to reimplement both that and the matrix multiplication A(rows, k) * A(k, rows) using explicit loops.
Your original Matlab code was (Matlab has 1-based indexing):
for k = 1:n - 1
rows = k + 1:n
A(rows, k) = A(rows, k) / A(k, k)
A(rows, rows) = A(rows, rows) - A(rows, k) * A(k, rows)
end
What rows = k + 1:n this does is that it sets rows to represent a range. The expression A(rows, k) is actually a reference to a vector-shaped slice of the matrix, and Matlab can divide a vector by a scalar.
On the last line, A(rows, rows) is a matrix-shaped slice , and A(rows, k) * A(k, rows) is a matrix multiplication, e.g. multiplying matrices of dimension (1,3) and (3,1) to get one of (3,3).
In C you can't do that using the builtin = and / operators.
The C equivalent is:
for ( int k = 0; k < n - 1; ++k )
{
// A(rows, k) = A(rows, k) / A(k, k)
for ( int row = k + 1; row < n; ++row )
A[row][k] /= A[k][k];
// A(rows, rows) = A(rows, rows) - A(rows, k) * A(k, rows)
for ( int row = k + 1; row < n; ++row )
for ( int col = k + 1; col < n; ++col )
A[row][col] -= A[row][k] * A[k][col];
}
(disclaimer: untested!)
The first part is straightforward: every value in a vector is being divided by a scalar.
However, the second line is more complicated. The Matlab code includes a matrix multiplication and a matrix subtraction ; and also the operation of extracting a sub-matrix from a matrix. If we tried to write a direct translation of that to C, it is very complicated.
We need to use two nested loops to iterate over the rows and columns to perform this operation on the square matrix.

How to efficiently store a triangular matrix in memory?

I want to store a lower triangular matrix in memory, without storing all the zeros.
The way I have implemented it is by allocating space for i + 1 elements on the ith row.
However, I am new to dynamic memory allocation in C and something seems to be wrong with my first allocation.
int main ()
{
int i, j;
int **mat1;
int dim;
scanf("%d", &dim);
*mat1 = (int**) calloc(dim, sizeof(int*));
for(i = 0; i < dim; i++)
mat1[i] = (int*) calloc(i + 1, sizeof(int));
for(i = 0; i < dim; i++)
{
for(j = 0; j < i + 1; j++)
{
scanf("%d", &mat1[i][j]);
}
}
/* Print the matrix without the zeros*/
for(i = 0; i < dim; i++)
{
for(j = 0; j < (i + 1); j++)
{
printf("%d%c", mat1[i][j], j != (dim-1) ? ' ' : '\n');
}
}
return 0;
}
If you want to conserve space and the overhead of allocating every row of the matrix, you could implement a triangular matrix by using clever indexing of a single array.
A lower triangular matrix (including diagonals) has the following properties:
Dimension Matrix Elements/row Total elements
1 x . . . 1 1
2 x x . . 2 3
3 x x x . 3 6
4 x x x x 4 10
...
The total number of elements for a given dimension is:
size(d) = 1 + 2 + 3 + ... + d = (d+1)(d/2)
If you lay the rows out consecutively in a single array, you can use the formula above to calculate the offset of a given row and column (both zero-based) inside the matrix:
index(r,c) = size(r-1) + c
The formulas above are for the lower triangular matrix. You can access the upper matrix as if it was a lower matrix by simply reversing the indexes:
index((d-1)-r, (d-1)-c)
If you have concerns about changing the orientation of the array, you can devise a different offset calculation for the upper array, such as:
uindex(r,c) = size(d)-size(d-r) + c-r
Sample code:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define TRM_SIZE(dim) (((dim)*(dim+1))/2)
#define TRM_OFFSET(r,c) (TRM_SIZE((r)-1)+(c))
#define TRM_INDEX(m,r,c) ((r)<(c) ? 0 : (m)[TRM_OFFSET((r),(c))])
#define TRM_UINDEX(m,r,c,d) ((r)>(c)?0:(m)[TRM_SIZE(d)-TRM_SIZE((d)-(r))+(c)-(r)])
#define UMACRO 0
int main (void)
{
int i, j, k, dimension;
int *ml, *mu, *mr;
printf ("Enter dimension: ");
if (!scanf ("%2d", &dimension)) {
return 1;
}
ml = calloc (TRM_SIZE(dimension), sizeof *ml);
mu = calloc (TRM_SIZE(dimension), sizeof *mu);
mr = calloc (dimension*dimension, sizeof *mr);
if (!ml || !mu || !mr) {
free (ml);
free (mu);
free (mr);
return 2;
}
/* Initialization */
srand (time (0));
for (i = 0; i < TRM_SIZE(dimension); i++) {
ml[i] = 100.0*rand() / RAND_MAX;
mu[i] = 100.0*rand() / RAND_MAX;
}
/* Multiplication */
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
for (k = 0; k < dimension; k++) {
mr[i*dimension + j] +=
#if UMACRO
TRM_INDEX(ml, i, k) *
TRM_UINDEX(mu, k, j, dimension);
#else
TRM_INDEX(ml, i, k) *
TRM_INDEX(mu, dimension-1-k, dimension-1-j);
#endif
}
}
}
/* Output */
puts ("Lower array");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
printf (" %2d", TRM_INDEX(ml, i, j));
}
putchar ('\n');
}
puts ("Upper array");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
#if UMACRO
printf (" %2d", TRM_UINDEX(mu, i, j, dimension));
#else
printf (" %2d", TRM_INDEX(mu, dimension-1-i, dimension-1-j));
#endif
}
putchar ('\n');
}
puts ("Result");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
printf (" %5d", mr[i*dimension + j]);
}
putchar ('\n');
}
free (mu);
free (ml);
free (mr);
return 0;
}
Note that this is a trivial example. You could extend it to wrap the matrix pointer inside a structure that also stores the type of the matrix (upper or lower triangular, or square) and the dimensions, and write access functions that operate appropriately depending on the type of matrix.
For any non-trivial use of matrices, you should probably use a third-party library that specializes in matrices.
mat1 = calloc(dim,sizeof(int*));
mat1 is a double pointer.You need to allocate memory for your array of pointers and later you need to allocate memory to each of your pointers individually.No need to cast calloc()
You are dereferencing mat1 at line 8 before it has even been set to point anywhere. You are allocating an array of pointers to int, but you are not assigning that to mat1 but to the dereference of mat1, which is uninitialized, we don't know what it points to.
So this line:
// ERROR: You are saying an unknown memory location should have the value of calloc.
*mat1 = (int**)calloc(dim,sizeof(int*));
Should change to:
// OK: Now you are assigning the allocation to the pointer variable.
mat1 = (int**)calloc(dim,sizeof(int*));

Resources