updating array's address by reference - c

As a part of my homework I have to make a function which gets a dynamic matrix and finds the matrix's elements which is equal to the sum of it's (i+j), also it have to return by value the array's size and return by reference the array.
Actually I have finished with the size part and all the function, what I dont get it how can I send from main to the function an arr of struct (cuz its not initialized yet), and how can I update it in the function.
Thanks!
typedef struct Three { // struct for the elements
int i;
int j;
int value;
}Three;
typedef struct List { // linked list struct
Three node;
struct List *next;
}List;
Three CreateThree(int i, int j, int value);
List *CreateThreeList(int **Mat, int rows, int cols);
Three *CreateThreeArr(int **Mat, int rows, int cols, int *newsize);
int CreateArrAndList(int **Mat, int rows, int cols);
void main() {
int **mat;
int row, col, i, j, value, arr_size;
printf("Please select the number of Rows and Cols in Matrix :\n");
printf("Rows: ");
scanf("%d", &row);
printf("Columns: ");
scanf("%d", &col);
mat = (int**)malloc(row * sizeof(int));
for (i = 0; i<col; i++)
mat[i] = (int*)malloc(col * sizeof(int));
printf("Please select %d values to your matrix:\n", row*col);
for (i = 0; i<row; i++)
{
for (j = 0; j<col; j++)
{
printf("select value for [%d][%d]: ", i, j);
scanf("%d", &value);
mat[i][j] = value;
}
}
arr_size = CreateArrAndList(mat, row, col);
}
Three CreateThree(int i, int j, int value) {
Three node;
node.i = i;
node.j = j;
node.value = value;
return node;
}
List *CreateThreeList(int **Mat, int rows, int cols) {
int i, j;
List *lst = NULL;
List *currLst = lst;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if ((i + j) == Mat[i][j]) {
List *tmp = (List*)malloc(sizeof(List));
tmp->node = CreateThree(i, j, Mat[i][j]);
tmp->next = NULL;
if (currLst == NULL) {
lst = tmp;
}
else {
currLst->next = tmp;
}
currLst = tmp;
}
}
}
return lst;
}
Three *CreateThreeArr(int **Mat, int rows, int cols, int *newsize) {
int i, j, arrIndex = 0, size = 0;
Three *arr;
arr = (Three*)malloc((rows*cols) * sizeof(Three));
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if ((i + j) == Mat[i][j]) {
arr[arrIndex++] = CreateThree(i, j, Mat[i][j]);
size++;
}
}
}
arr = (Three*)realloc(arr,size * sizeof(Three));
*newsize = size;
return arr;
}
int CreateArrAndList(int **Mat, int rows, int cols) {
int arrSize;
Three *arr = CreateThreeArr(Mat, rows, cols, &arrSize);
List *lst = CreateThreeList(Mat, rows, cols);
return arrSize;
}

ptrdiff_t create_arr_and_list(int **mat, ptrdiff_t rows, ptrdiff_t cols, struct three **arr, struct list **lst)
{
ptrdiff_t nmemb;
*arr = create_three_arr(mat, rows, cols, &nmemb);
*lst = create_three_list(mat, rows, cols);
return nmemb;
}
You can create a pointer in main (struct three *arr;, and struct list *lst;), pass a pointer to a those pointers (create_arr_and_list(mat, rows, cold, &arr, &lst);), and you initialize them later in the function.
int main(void)
{
int **mat;
int value
ptrdiff_t row, col, nmemb;
struct three *arr;
struct list *lst;
printf("Please select the number of Rows and Cols in Matrix :\n");
printf("Rows: ");
scanf("%ti", &row);
printf("Columns: ");
scanf("%ti", &col);
mat = malloc(sizeof(*mat) * row);
for (i = 0; i < col; i++)
mat[i] = malloc(sizeof(*mat[i]) * col);
printf("Please select %ti values to your matrix:\n", row * col);
for (ptrdiff_t i = 0; i < row; i++) {
for (ptrdiff_t j = 0; j < col; j++) {
printf("select value for [%ti][%ti]: ", i, j);
scanf("%d", &value);
mat[i][j] = value;
}
}
nmemb = create_arr_and_list(mat, rows, cold, &arr, &lst);
}

Related

Function inputElements() taking input only once

I am trying to create a program to find the transpose of a matrix my dynamic memory allocation. However, while entering the elements of the matrix I can't input more than one element, its only taking the a[0][0] as the input and the program is ending after that.
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int **, int, int);
void inputElements(int **, int, int);
void transpose(int **, int **, int, int);
void display(int **, int, int);
void main()
{
int **matrix, **trans, rows, cols;
printf("\nEnter number of rows in the matrix: ");
scanf("%d", &rows);
printf("\nEnter number of columns in the matrix: ");
scanf("%d", &cols);
createMatrix(matrix, rows, cols);
createMatrix(trans, cols, rows);
inputElements(matrix, rows, cols);
transpose(matrix, trans, rows, cols);
printf("\nMATRIX:\n");
display(matrix, rows, cols);
printf("\nTRANSPOSE OF THE MATRIX:\n");
display(trans, rows, cols);
}
void createMatrix(int **a, int r, int c) //for allocating memory for the matrix
{
int i, j;
a = (int **)malloc(sizeof(int *) * r);
for(i = 0; i < r; i++)
a[i] = (int *)malloc(sizeof(int) * c);
}
void inputElements(int **a, int r, int c) //for entering matrix elements
{
int i, j, t;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("\nEnter matrix element[%d][%d]: ", i + 1, j + 1);
fflush(stdin);
getchar();
scanf("%d", &(a[i][j]));
}
}
}
void transpose(int **a, int **t, int r, int c) //for finding out the transpose of the matrix
{
int i, j;
for (i = 0; i < c; i++)
{
for (j = 0; j < r; j++)
t[i][j] = a[j][i];
}
}
void display(int **a, int r, int c) //for displaying the matrix
{
int i, j;
for (i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
printf("\t%d", a[i][j]);
}
}
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.

How to change the content of a 2d array in C?

I am working on a problem where I have to transpose a matrix. I am passing the address of the original matrix, but once I execute the function it does not change!
I have tried to add a * infront of matrix in the transpose function, thinking that it will be pointing to the whole 2d array, but it did not work.
#include<stdio.h>
#include <stdlib.h>
void transpose(int *r,int *c, int **matrix);
void printMatrix(int r,int c, int **matrix){
for(int i=0;i<r;i++){
for(int j=0;j<c;j++)
printf("%2d ",matrix[i][j]);
printf("\n");
}
}
int main() {
int **matrix;
int r =3;
int c =2;
matrix = (int**) malloc(r*sizeof(int*));
for(int i=0;i<r;i++)
matrix[i] = (int*) malloc(c*sizeof(int));
for(int i=0;i<r;i++){
for(int j=0;j<c;j++)
matrix[i][j] = (3*i+2*j)%8+1;
}
printf("Before transpose:\n");
printMatrix(r,c,matrix);
transpose(&r, &c ,matrix);
printMatrix(r,c,matrix);
return 0;
}
void transpose(int *r,int *c, int **matrix){
int newR = *c;
int newC = *r;
int **newMatrix;
newMatrix = (int**) malloc(newR*(sizeof(int*)));
for(int i=0; i<newR;i++)
newMatrix[i] = (int*) malloc(newC*(sizeof(int)));
for(int i=0; i<newR; i++)
for(int j=0;j<newC;j++)
newMatrix[i][j] = matrix[j][i];
*c = newC;
*r = newR;
matrix = (int**) malloc((*r)*sizeof(int*));
for(int i=0;i<*r;i++)
matrix[i] = (int*) malloc((*c)*sizeof(int));
for(int i=0; i<newR; i++){
for(int j=0;j<newC;j++){
matrix[i][j] = newMatrix[i][j];
}
printf("\n");
}
}
I have this matrix
1 3
4 6
7 1
and want to get
1 4 7
3 6 1
however I am getting
1 3 0
1 4 0
It looks like all you forgot to do was actually use the transposed matrix. All I did was change the function signature and return the matrix you had already allocated and manipulated, and I got the output you were looking for.
#include <stdio.h>
#include <stdlib.h>
int** transpose(int *r,int *c, int **matrix);
void printMatrix(int r, int c, int **matrix) {
for (size_t i = 0; i < r; ++i){
for (size_t j = 0; j < c; ++j) {
printf("%2d ",matrix[i][j]);
}
printf("\n");
}
}
int main()
{
int r = 3;
int c = 2;
int **matrix = calloc(sizeof(int*), r);
for (size_t i = 0; i < r; ++i) {
matrix[i] = calloc(sizeof(int), c);
}
for (size_t i = 0; i < r; ++i) {
for (size_t j = 0; j < c; ++j) {
matrix[i][j] = (3 * i + 2 * j) % 8 + 1;
}
}
printf("Before transpose:\n");
printMatrix(r, c, matrix);
int** newMatrix = transpose(&r, &c ,matrix);
printMatrix(r, c, newMatrix);
return EXIT_SUCCESS;
}
int** transpose(int *r, int *c, int **matrix) {
int newR = *c;
int newC = *r;
int **newMatrix = calloc((sizeof(int*)), newR);
for (size_t i = 0; i < newR; ++i) {
newMatrix[i] = (int*) malloc(newC*(sizeof(int)));
}
for (size_t i = 0; i < newR; ++i) {
for (size_t j = 0; j < newC; ++j) {
newMatrix[i][j] = matrix[j][i];
}
}
*c = newC;
*r = newR;
matrix = calloc(sizeof(int*), *r);
for (size_t i = 0; i < *r; ++i) {
matrix[i] = calloc(sizeof(int), *c);
}
for (size_t i = 0; i < newR; ++i) {
for (size_t j = 0; j < newC; ++j) {
matrix[i][j] = newMatrix[i][j];
}
printf("\n");
}
return newMatrix;
}
Output:
1 4 7
3 6 1
I changed a few things, especially because I prefer using calloc over malloc, since it zeroes out the newly-allocated memory, and there is a dedicated parameter for the size of the requested memory, which I think semantically is a better idea.
As a side note, you don't have to cast the result of malloc in C. I tend to feel more strongly about that than other people, I think, because code noise, especially when you're working in C is one of the worst things you can do to yourself. This is a pretty good example of that, since all I did was reformat your code and the answer was right there. Don't be stingy with the whitespace, either; it really does make a difference.
Anyways, I hope this helped somewhat, even if you literally had basically everything done.
#include<stdio.h>
#include <stdlib.h>
void transpose(int *r,int *c, int ***matrix);
void printMatrix(int r,int c, int **matrix){
int i=0,j=0;
for(i=0;i<r;i++){
for(j=0;j<c;j++)
printf("%2d ",matrix[i][j]);
printf("\n");
}
}
int main() {
int **matrix;
int r =3;
int c =2;
int i=0,j=0;
matrix = (int**) malloc(r*sizeof(int*));
for(i=0;i<r;i++)
matrix[i] = (int*) malloc(c*sizeof(int));
for(i=0;i<r;i++){
for(j=0;j<c;j++)
matrix[i][j] = (3*i+2*j)%8+1;
}
printf("Before transpose:\n");
printMatrix(r,c,matrix);
transpose(&r, &c, &matrix);
printMatrix(r,c,matrix);
return 0;
}
void transpose(int *r,int *c, int ***matrix){
int newR = *c;
int newC = *r;
int **newMatrix;
int i=0,j=0;
newMatrix = (int**) malloc(newR*(sizeof(int*)));
for(i=0; i<newR;i++)
newMatrix[i] = (int*) malloc(newC*(sizeof(int)));
for(i=0; i<newR; i++)
for(j=0;j<newC;j++) {
newMatrix[i][j] = (*matrix)[j][i];
}
*c = newC;
*r = newR;
// free matrix..
*matrix = newMatrix;
/*matrix = (int**) malloc((*r)*sizeof(int*));
for(i=0;i<*r;i++)
matrix[i] = (int*) malloc((*c)*sizeof(int));
for(i=0; i<newR; i++){
for(j=0;j<newC;j++){
matrix[i][j] = newMatrix[i][j];
}
printf("\n");
}*/
}

Unhandled exception when adding a value to struct member in 2D array

I am writing a Theater program using a dynamic 2D array. To store a booking details I use structure.
When I try to initialize one of the variables inside each index of 2D array, I receive unhandled exception error.
Function with error:
void initializing_tickets(ticket **arrayPtr, int row, int col){
int i, j, counter;
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
(*(arrayPtr + i) + j) -> id = 0; // debugger explains that expression cannot be evaluated
printf("%d ", (*(arrayPtr + i) + j) -> id);
}
printf("\n");
}
} //end of initializing_tickets()
My program so far:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
/* Structures */
typedef struct Theater
{
int id;
int status;
char name[20];
char phone[15];
} ticket;
/* Global variables */
ticket **array2D; // pointer to a 2D array
/* Constructors */
void create_Theater(int *row, int* col);
void test();
void loop_array(ticket **arrayPtr, int row, int col);
void initializing_tickets(ticket **arrayPtr, int row, int col);
int main(void)
{
int row = 0, col = 0;
create_Theater(&row,&col);
initializing_tickets(array2D, row, col);
//loop_array(array2D, row, col);
//test();
printf("\n\n");
system("pause");
return(0);
}
void create_Theater(int *row, int* col)
{
int r = 0, c = 0;
int i;
assert(row);
assert(col);
*row = r;
*col = c;
printf("Please enter the row dimensions of the Theater\n");
scanf("%d", row);
printf("Please enter the column dimensions of the Theater\n");
scanf("%d", col);
array2D = (ticket**)malloc(r*sizeof(ticket*));
for (i = 0;i<r;i++)
{
array2D[i] = (ticket*)malloc(c*sizeof(ticket));
}
} // end of create_Theater()
void initializing_tickets(ticket **arrayPtr, int row, int col){
int i, j, counter;
for(i = 0; i < row; i++)
{
for(j = 0; j < col; j++)
{
(*(arrayPtr + i) + j) -> id = 0; // debugger explains that expression cannot be evaluated
printf("%d ", (*(arrayPtr + i) + j) -> id);
}
printf("\n");
}
} //end of initializing_tickets()
void loop_array(ticket **arrayPtr, int row, int col)
{
int i, j;
for(i = 0; i < row; i++)
{
printf("Row is ok");
for(j = 0; j < col; j++)
{
printf("Col is ok");
}
}
}
I think array is not allocated properly to a memory, but I can't find a mistake.
Thank you for attention!
Change your function to:
void create_Theater(int* row, int* col){
int i;
assert(row);
assert(col);
printf("Please enter the row dimensions of the Theater\n");
scanf("%d", row);
printf("Please enter the column dimensions of the Theater\n");
scanf("%d", col);
array2D = (ticket**)malloc((*row)*sizeof(ticket*));
for (i = 0;i<(*row);i++)
{
array2D[i] = (ticket*)malloc((*col)*sizeof(ticket));
}
} // end of create_Theater()
It works.

2D array, sort rows by sum

There is 2D array with pointers from user, filled with random numbers, program count sum of every row. I need to sort array by sum of every row and print it. For example if we have array:1 2 2 (sum=5)2 9 9 (sum=20)2 1 6 (sum=9)
output should be:1 2 2 (sum=5)2 1 6 (sum=9)2 9 9 (sum=20). Thanks for help.
int main () {
int i, j, row, column, **array,sum;
time_t seconds;
time (&seconds);
srand ((unsigned int)seconds );
printf ("Write number of rows:");
scanf ("%d", &row);
printf ("Write number of columns:");
scanf ("%d", &column);
array=(int**) malloc (row * sizeof(int *));
if (array!=NULL){
for (i=0; i<row;i++)
array[i]= (int*) malloc (column *sizeof(int));
}
for (i=0; i<row;i++)
for (j=0; j<column;j++)
array[i][j]=(rand()%100);
for (i=0; i<row;i++){
for (j=0; j<column;j++)
printf("%d ",array[i][j] );
printf ("\n");
}
for(i=0;i<row;i++){ //find sum of each row
sum=0;
for(j=0;j<column;j++){
sum=sum+array[i][j];
}
printf("%d \n",sum);
}
return 0;
}
sample of option 1
#include <stdio.h>
#include <stdlib.h>
int COLUMNS;
int sum(int len, int *array){
int i, sum = 0;
for(i=0; i<len; ++i)
sum += *array++;
return sum;
}
int cmp(const void *a, const void *b){
int sum1 = sum(COLUMNS, *(int**)a);
int sum2 = sum(COLUMNS, *(int**)b);
return (sum1 > sum2) - (sum1 < sum2);
}
int main(void){
int i, j, row, column, **array;
row = 3; column = 3;
array = (int**) malloc (row * sizeof(*array));//cast of (int**) is redundant.
array[0] = (int []){1, 2, 2};
array[1] = (int []){2, 9, 9};
array[2] = (int []){2, 1, 6};
COLUMNS = column;//size of columns pass to compare function by global variable.
qsort(array, row, sizeof(*array), cmp);
for (i=0; i<row;i++){
for (j=0; j<column;j++)
printf("%d ",array[i][j] );
printf ("\n");
}
free(array);
return 0;
}
sample of option 2
#include <stdio.h>
#include <stdlib.h>
int sum(int len, int *array){
int i, sum = 0;
for(i=0; i<len; ++i)
sum += *array++;
return sum;
}
typedef struct pair {
int *p;//or index
int sum;
} Pair;
int cmp(const void *a, const void *b){
Pair const *x = a;
Pair const *y = b;
return (x->sum > y->sum) - (x->sum < y->sum);
}
int main(void){
int i, j, row, column, **array;
row = 3; column = 3;
array = (int**) malloc (row * sizeof(*array));//cast of (int**) is redundant.
array[0] = (int []){1, 2, 2};
array[1] = (int []){2, 9, 9};
array[2] = (int []){2, 1, 6};
Pair *temp = malloc(row * sizeof(*temp));
for(i = 0; i < row; ++i){
temp[i].p = array[i];
temp[i].sum = sum(column, array[i]);
}
qsort(temp, row, sizeof(*temp), cmp);
for (i=0; i<row;i++){
for (j=0; j<column;j++)
printf("%d ", temp[i].p[j] );
printf ("\n");
}
free(temp);
free(array);
return 0;
}

crash on trying to reallocate a pointer using pointer to this pointer

I have a pointer to a pointer ("paths") and I want to reallocate each pointer (each "path"). But I get a crash. Generally I am trying to find all possible powers of a number, which one can compute for some amount of operations (e.g for two operations we can get power of three and four (one operation for square of a number, then another one either for power of three or four)). I figured out how to do it on paper, now I am trying to implement it in code. Here is my try:
#include <stdio.h>
#include <stdlib.h>
void print_path(const int *path, int path_length);
int main(void)
{
fputs("Enter number of operations? ", stdout);
int operations;
scanf("%i", &operations);
int **paths, *path, npaths, npath;
npaths = npath = 2;
path = (int*)malloc(npath * sizeof(int));
paths = (int**)malloc(npaths * sizeof(path));
int i;
for (i = 0; i < npaths; ++i) // paths initialization
{
int j;
for (j = 0; j < npath; ++j)
paths[i][j] = j+1;
}
for (i = 0; i < npaths; ++i) // prints the paths, all of them are displayed correctly
print_path(paths[i], npath);
for (i = 1; i < operations; ++i)
{
int j;
for (j = 0; j < npaths; ++j) // here I am trying to do it
{
puts("trying to reallocate");
int *ptemp = (int*)realloc(paths[j], (npath + 1) * sizeof(int));
puts("reallocated"); // tried to write paths[j] = (int*)realloc...
paths[j] = ptemp; // then tried to make it with temp pointer
}
puts("memory reallocated");
++npath;
npaths *= npath; // not sure about the end of the loop
paths = (int**)realloc(paths, npaths * sizeof(path));
for (j = 0; j < npaths; ++j)
paths[j][npath-1] = paths[j][npath-2] + paths[j][j];
for (j = 0; j < npaths; ++j)
print_path(paths[j], npath);
puts("\n");
}
int c;
puts("Enter e to continue");
while ((c = getchar()) != 'e');
return 0;
}
void print_path(const int *p, int pl)
{
int i;
for (i = 0; i < pl; ++i)
printf(" A^%i -> ", p[i]);
puts(" over");
}
I am not sure the problem resides with the call to realloc(), rather you are attempting to write to locations for which you have not created space...
Although you create memory for the pointers, no space is created (allocate memory) for the actual storage locations.
Here is an example of a function to allocate memory for a 2D array of int:
int ** Create2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
Use example:
#include <ansi_c.h>
int main(void)
{
int **array=0, i, j;
array = Create2D(array, 5, 4);
for(i=0;i<5;i++)
for(j=0;j<4;j++)
array[i][j]=i*j; //example values for illustration
free2DInt(array, 5);
return 0;
}
Another point here is that it is rarely a good idea to cast the return of [m][c][re]alloc() functions
EDIT
This illustration shows my run of your code, just as you have presented it:
At the time of error, i==0 & j==0. The pointer at location paths[0][0] is uninitialized.
EDIT 2
To reallocate a 2 dimension array of int, you could use something like:
int ** Realloc2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = realloc(arr, space*sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
And here is a test function demonstrating how it works:
#include <stdio.h>
#include <stdlib.h>
int ** Create2D(int **arr, int cols, int rows);
void free2DInt(int **arr, int cols);
int ** Realloc2D(int **arr, int cols, int rows);
int main(void)
{
int **paths = {0};
int i, j;
int col = 5;
int row = 8;
paths = Create2D(paths, col, row);
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<5;i++)
{
for(j=0;j<8;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
//reallocation:
col = 20;
row = 25;
paths = Realloc2D(paths, col, row);
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
paths[i][j]=i*j;
}
}
j=0;
for(i=0;i<20;i++)
{
for(j=0;j<25;j++)
{
printf("%d ", paths[i][j]);
}
printf("\n");
}
free2DInt(paths, col);
getchar();
return 0;
}
The realloc() does not fail. What fails is that you haven't allocated memory for the new pointers between paths[previous_npaths] and paths[new_npaths-1], before writing to these arrays in the loop for (j = 0; j < npaths; ++j).

Resources