How to populate a bidimensional array in the reverse way - C - c

I'm trying to populate a bidimensional array in the reverse way but I'm getting always the same error: core dump.
When I say reverse way I mean, usually we do something like
for(int i=0; i<MaxColumns; i++)
for(int b=0; i<MaxRows; b++)
array[i][b] = random value;
What I'm trying to do is for each row, I want to populate that single row on every column and then pass to the next row and do the same. At this time I'm declaring dynamically a new row for each column.
This is what I was trying:
int i = atoi(argv[1]);
int **array = (int**)malloc(i * sizeof(int*));
for (lines =0; lines <MAXLINES; lines ++) {
for (colunms =0; colunms <i; colunms ++) {
array[colunms] = (int*)malloc(1 * sizeof(int));
v=colunms+lines;
array[colunms][lines]=v;
}
}
And the error goes on:
array[colunms][lines]=v;
------ LAST UPDATE TO PROBLEM ----
Already updated and although I tried this code
for (lines =0; lines <MAXLINES; lines ++) {
array[colunms] = (int*)malloc(colunms * sizeof(int));
for (colunms =0; colunms <i; colunms ++) {
v=colunms+lines;
array[colunms][lines]=v;
}
}
I keep getting core dumped on:
array[colunms][lines]=v;

Thats simple enough. Instead of:
for(int i=0; i<MaxColumns; i++)
for(int b=0; i<MaxRows; b++)
array[i][b]=random value;
Use:
for(int b=0; i<MaxRows; b++)
for(int i=0; i<MaxColumns; i++)
array[i][b]=random value;
Your error though is in:
array[colunms] = (int*)malloc(1 * sizeof(int));
You are allocating space for 1 element of int where you should be allocating for colunms * sizeof(int). You should also do that outside the inner loop, like this:
int **array = (int**)malloc(MAXLINES * sizeof(int*));
for (lines =0; lines <MAXLINES; lines ++) {
array[lines] = (int*)malloc(i * sizeof(int));
for (colunms =0; colunms <i; colunms ++) {
v=colunms+lines;
array[lines][colunms] = v;
}
}
Also, even though this code should work, it can be a problem in the future to assume this as array[colunms][lines] where it should be array[lines][colunms].
Why? Because with array[lines][colunms] each array[line] represents a complete row with all its columns, which is a lot more practical for most cases.
In this form you will be able to declare functions to handle single records instead of handing it the entire "table".

Related

Arrays in C programming

I was working on the following 2d-array program to output this result shown in picture:
I can't seem to get the min value for the result and get it displayed in array form.
The code is below:
#include<stdio.h>
#define NUMROWS 2
#define NUMCOLS 3
//accessing elements of 2D array using pointers
int main(void){
const int table[NUMROWS][NUMCOLS]={{1,2,3},{5,6,7}};
int minvals[NUMROWS];
int i, j;
int *ptr = &table;
//accessing the elements of 2D array using ptr
printf("table values: min value\n");
for(int i=0;i<NUMROWS;i++){
for(int j=0;j<NUMCOLS;j++)
printf("%d ",*((ptr+i*NUMCOLS)+j));
printf("\n");
}
for(int i=0;i<NUMROWS;i++){
for(int j=0;j<NUMCOLS;j++)
printf("%d ",*((ptr+i*NUMCOLS)+j)<minvals[i]);
}
return 0;
}
The existence of minvals would imply that you are expected to calculate the minimum value of each 'row' of table before then moving on to printing. As it stands, had your program properly calculated the minimum values of each array, your printing would be rather out of order.
There's no need to do any tricky, manual pointer manipulation. Simple array subscription is much clearer.
Let's start simple and return to basics by looking at the way we find the minimum value in a one dimensional array, as it is the core of this problem.
To find the minimum value in an array we need a few things to start:
An array
The length of the array
An initial value to compare against
The array itself is obviously each subarray of table, and the length in this case is known to be NUMCOLS. Our initial value should either be INT_MAX (or another type-appropriate maximum constant found <limits.h>), such that every element in the array is equal to or less than our initial value, or a value from the array itself.
Often times we opt for the second option here, choosing the first element in the array as our initial value, and comparing it to the second and onward elements.
As such, finding the minimum value in a single 'row' would look like this
const int row[NUMCOLS] = { 9, 2, 5 };
int min = row[0];
for (int i = 1; i < NUMCOLS; i++)
if (row[i] < min)
min = row[i];
but since we want to find and record the minimum value of each 'row' in table, we're going to use a nested loop. Instead of the min variable from before, we store each value in the associated index of our minvals array.
for (i = 0; i < NUMROWS; i++) {
minvals[i] = table[i][0];
for (j = 1; j < NUMCOLS; j++)
if (table[i][j] < minvals[i])
minvals[i] = table[i][j];
}
When it comes time to print, we're going to repeat our nested loop. Our inner loop prints each element of each 'row' of table, and we end each iteration of the outer loop by printing the value found in minvals with the same index of our 'row'.
for (i = 0; i < NUMROWS; i++) {
for (j = 0; j < NUMCOLS; j++)
printf("%6d", table[i][j]);
printf(":%6d\n", minvals[i]);
}
Here's a working example.
#include <stdio.h>
#define NUMROWS 2
#define NUMCOLS 3
int main(void) {
const int table[NUMROWS][NUMCOLS] = {
{ 9, 2, 5 },
{ 3, -4, -12 }
};
int minvals[NUMROWS];
int i, j;
for (i = 0; i < NUMROWS; i++) {
minvals[i] = table[i][0];
for (j = 1; j < NUMCOLS; j++)
if (table[i][j] < minvals[i])
minvals[i] = table[i][j];
}
puts("Table value: minimum values");
for (i = 0; i < NUMROWS; i++) {
for (j = 0; j < NUMCOLS; j++)
printf("%6d", table[i][j]);
printf(":%6d\n", minvals[i]);
}
}
A good further exercise for you would be to compose the logic of the inner loop for finding minimum values into a more generic function. Its function signature would look like
int min(int *array, size_t length);
allowing it to work on arrays of varying sizes. Then our outer loop could be as simple as:
for (i = 0; i < NUMROWS; i++)
minvals[i] = min(table[i], NUMCOLS);
The line
int *ptr = &table;
is wrong, because &table is of type int (*)[2][3] (i.e. a pointer to the entire table), whereas ptr is a pointer to a single element. Also, your pointer is non-const, so it cannot point be made to point into a const array.
If you want ptr to point to a single int value, then you should declare it the following way:
const int *ptr = &table[0][0];
Also, you are reading the contents of the array minvals, although that array contains uninitialized data. This does not make sense and causes undefined behavior.
Instead of doing complex pointer arithmetic with the expression
*((ptr+i*NUMCOLS)+j))
you can simply write the following:
table[i][j]
That way, you do not need the pointer ptr and your code is simpler.

Allocating a 2d integer array in C

I'm trying to dynamically allocate a 2D INT array in C in order to return a transposed matrix, I've done several research on the topic, and it should work this way, however I keep struggling with the program.
I tried it many different ways now (offset, pointer arithmetic), I didn't find a fix for the problem.
I'm either getting trash values or the program crashes (no seg fault, error code crash).
I'm also loooking for a proper version to allocate the memory, I've seen several versions on stackoverflow, the one I would preferrably like to use, is allocating pointer space and the integer space afterwards (the one I'm trying to use in the example below).
// Convert a matrix to it's transposed version. Returns a two dimensional array (pointer)
int **getTransposedMatrix(int *matrix, int dimension_h, int dimension_w){
int **transposedMatrix = (int **) malloc(dimension_w * sizeof(int*));
for(int row=0; row<dimension_w; row++){
transposedMatrix[row] = (int*) malloc(dimension_w * sizeof(int));
}
for(int row=0; row<dimension_h; row++){
for(int column=0; column<dimension_w; column++){
transposedMatrix[column][row] = *(matrix + row * dimension_w + column);
printf("%d ", transposedMatrix + (row * dimension_w + column));
}
printf("\n");
}
return **transposedMatrix;
}
I appreciate any help :)
I would not bother with a "2D array" such as the one you are setting up, where you're allocating the rows separately. Below is my version which uses a single array and calculates offsets into it accordingly.
int *getTransposedMatrix(int *matrix, int dimension_w, int dimension_h)
{
int *transposed = malloc(dimension_w * dimension_h * sizeof(int));
for (int row = 0; row < dimension_h; row++) {
for (int col = 0; col < dimension_w; col++) {
transposed[col * dimension_h + row] = matrix[row * dimension_w + col];
}
}
return transposed;
}
ideone with some test examples

How can I delete N number of rows and columns of a 2d array selected by the user in c

I am writing a piece of code that uses a struct containing a 2d array and predetermined functions which I have listed with comments describing what the function does.
struct matrix
{
char name;
int mValues[10][10[;
int nrows;
int ncols;
};
/** Function Prototypes**/
// Lets user name, choose dimensions and populates matrix from a 10x10 .txt file
void matrixInput(struct matrix *matA);
// Asks the user to choose how many rows to delete and select which rows
// Asks the user to choose how many columns to delete and select which columns.
// The result should be a sub matrix of the input matrix stored in a new struct matrix
void subMatrix(struct matrix m1, struct matrix *m2);
// What the Input/Output should look like
How many rows do you want to delete? : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 1
How many columns do you want to delete? : 3
Please enter, one per column, the number(s) of the 3 columns you want to delete : 4
Please enter, one per column, the number(s) of the 3 columns you want to delete : 2
Please enter, one per column, the number(s) of the 3 columns you want to delete : 5
// Displays sub matrix
It's the last function I am having problems with.
I know the size of the input matrix and I think that I need to some how tell the complier pass the values of the input matrix to the new struct matrix while excluding the value of the user input for row/col number to be deleted. I'm not sure if this could be done in a nested loop or if I would need other variables to store values.
I know how to read and pass values at a given index but I'm stuck for ideas when it comes to not reading and passing values at a given index.
Can anybody point me in the right direction?
Side note, any tips on how to improve the quality of my question is welcomed.
If you know which columns and rows to delete, and you are sure that the result is going to fit in the new matrix, then just do a nested loop and tell it to ignore a certain range of values.
But what you really want to do is create the new matrix inside the copying function and return it. If they are created dynamically you can ignore assignment of the columns or rows you are trying to copy in the same way (nested loops) and fit it exactly with the size you need.
You can't easily store delete information in a matrix, because matrix->values[0][0] could refer to either row or column. It's easier to declare to integers instead.
The function void subMatrix(struct matrix m1,...) is technically okay if you don't want to change m1, but this makes an extra copy of m1 which is not efficient. It's better to use void subMatrix(const struct matrix *source,...) instead.
You can also use dynamic allocation instead of fixed array of value[10][10]. Example:
struct matrix {
int **data;
int rows;
int cols;
};
void create(struct matrix *m, int rows, int cols)
{
m->rows = rows;
m->cols = cols;
m->data = malloc(rows * sizeof(int*));
for(int r = 0; r < rows; r++)
m->data[r] = malloc(sizeof(int) * cols);
}
void destroy(struct matrix *m)
{
for(int i = 0; i < m->rows; i++)
free(m->data[i]);
free(m->data);
}
void print(const struct matrix *m)
{
for(int r = 0; r < m->rows; r++)
{
for(int c = 0; c < m->cols; c++)
printf("%4d", m->data[r][c]);
printf("\n");
}
printf("\n");
}
void change(struct matrix *new, struct matrix *m, int *delete_rows, int *delete_cols)
{
int rows = 0;
for(int row = 0; row < m->rows; row++)
if(!delete_rows[row])
rows++;
int cols = 0;
for(int col = 0; col< m->cols; col++)
if(!delete_cols[col])
cols++;
create(new, rows, cols);
int next_row = 0;
for(int row = 0; row < m->rows; row++)
{
if(delete_rows[row]) continue;
int next_col = 0;
for(int col = 0; col < m->cols; col++)
{
if(delete_cols[col]) continue;
new->data[next_row][next_col] = m->data[row][col];
next_col++;
}
next_row++;
}
}
int main(void)
{
struct matrix m;
create(&m, 10, 10);
for(int r = 0; r < m.rows; r++)
for(int c = 0; c < m.rows; c++)
m.data[r][c] = r * 100 + c;
print(&m);
//get delete information
int delete_rows[10] = { 0 };
int delete_cols[10] = { 0 };
delete_rows[0] = 1;//delete row 0
delete_cols[7] = 1;//delete col 7
struct matrix new;
change(&new, &m, delete_rows, delete_cols);
print(&new);
destroy(&m);
destroy(&new);
return 0;
}

Getting value from dynamically allocated 2D array

I'm new to C programming so I am probably doing something really stupid here. I am trying to get the value from a 2D array that I read in from a text file ~70m lines.
When running the code, I get a seg fault and I have narrowed it down to line 10: if (i == graph[j][0])
void convertToCSR(int source, int maxNodes, int maxEdges, int* vertices, int* edges, int** graph) {
int i;
int j;
int edge = 0;
for (i = 0; i < maxNodes; i++) {
vertices[i] = edge;
for (j = 0; j < maxEdges; j++) {
if (i == graph[j][0]) {
//Sets edges[0] to the first position
edges[edge] = graph[j][1];
printf("new edge value: %d\n", edge);
edge++;
}
}
}
vertices[maxNodes] = maxEdges;}
I have tried this with smaller datasets e.g 50 bytes and it works fine. With further testing, I print out the value of graph[0][0] and I get a seg fault.
The graph has loaded the data and was allocated like this:
int num_rows = 69000000;
graph = (int**) malloc(sizeof(int*) * num_rows);
for(i=0; i < num_rows; i++){
graph[i] = (int*) malloc(sizeof(int) * 2 );
}
I am also able to get the value of graph[0][0] outside of this method but not inside.What am I doing wrong? I appreciate any help.
EDIT: In my main method, I am doing the following:
readInputFile(file);
int source = graph[0][0];
convertToCSR(source, maxNodes, maxEdges, nodes, edges, graph);
I have the correct value for the variable : source.
It seg faults in the convertToCSR method.
You’re using num_rows to store a number bigger than int capacity.
So the actual value int num_rows is not 69000000, because of the Overflow.
Try to use long unsigned int num_rows instead.

Conway's Game of Life (C) - Coordinates not Corresponding to 2D Array Indexing?

I am trying to program Conway's Game of Life in C. I have created a 2 dimensional array representing the cells. I attempted to solve the game using a system of coordinates.
I wrote a function to create an array that brute forced all possible combinations of the neighbor's coordinates.
Then I looped through the 2d array of cells using a double nested for loop, and counted the number of dead and living neighboring cells.
I have a conditional that checks if the neighboring cells are alive, dead, or non existing (this occurs if the cell in the game is on the edge or the corner of the array).
The only problem is, no matter what I try, I am always counting the wrong number of living and dead cells, which results in subsequent incorrect generations.
I'm pretty sure this is because the system of coordinates that I am using to keep track of the cells does not correspond to the arrays. (I have tried to fix this, and failed)
My question is, what is the correct way to access specific cells inside the 2D arrays, such that the rows and columns of the arrays correspond to the x and y axis?
void bruteforceNeighbors(int ** coord, int i, int j){
array[0][0] = i-1;
array[0][1] = j-1;
array[1][0] = i-1;
array[1][1] = j;
array[2][0] = i-1;
array[2][1] = j+1;
array[3][0] = i;
array[3][1] = j-1;
array[4][0] = i;
array[4][1] = j+1;
array[5][0] = i+1;
array[5][1] = j-1;
array[6][0] = i+1;
array[6][1] = j;
array[7][0] = i+1;
array[7][1] = j+1;
}
//world is the 2d array
char ** world = (char **)malloc(sizeof(char *)*rows);
for (int i =0;i < rows; i++){
world[i] = (char *) malloc(sizeof(char)*columns);
}
You are reserving space for an array of char * but using int ** inside the function, change to
int **world = malloc(sizeof(int *) * rows);
for (int i =0; i < rows; i++) {
world[i] = malloc(sizeof(int) * columns);
}

Resources