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

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.

Related

updating array's address by reference

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);
}

pass matrix by reference and scan values

I'm trying to scan values into a matrix that is passed by reference to a function and that's not compiled.
What's wrong?
I think the problem is in line of scanf but I don't know how to fix it.
#include <stdio.h>
#include <stdlib.h>
int** initMatrix(int lines, int columns) {
int i;
int** matrix;
matrix = (int**) calloc(lines, sizeof(int*));
for (i = 0; i < lines; i++) {
matrix[i] = (int*) calloc(columns, sizeof(int));
}
return matrix;
}
void fillMatrixValues(int*** matrixA, int lines, int columns) {
int i, j;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
scanf("%d", matrixA[i][j]);
}
}
}
void printMatrix(int** matrix, int lines, int columns) {
int i, j;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
printf("%d\t", matrix[i][j]);
}
printf("\n");
}
}
void main() {
int** matrixA;
int lines = 2, columns = 2;
matrixA = initMatrix(lines, columns);
fillMatrixValues(&matrixA, lines, columns);
printMatrix(matrixA, lines, columns);
}
void main -> undefined behaviour
Use
int main(void)
or
int main(int argc, char ** argv)
You should check return value of scanf
if (scanf("%d", matrixA[i][j]) != 1)
{
// failed
}
Next problem
void fillMatrixValues(int ***matrixA, int lines, int columns)
fillMatrixValues(&matrixA, lines, columns)
to
void fillMatrixValues(int **matrixA, int lines, int columns)
fillMatrixValues(matrixA, lines, columns)

Using scanf() with a pointer to a double pointer

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

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).

Passing a matrix in a function (C)

I have an issue passing a matrix to a function in C. There is the function I want to create:
void ins (int *matrix, int row, int column);
but I noticed that in contrast to the vectors, matrix give me an error. How can I pass my matrix to a function so?
EDIT --> there is the code:
// Matrix
#include <stdio.h>
#define SIZE 100
void ins (int *matrix, int row, int column);
void print (int *matrix, int row, int column);
int main ()
{
int mat[SIZE][SIZE];
int row, col;
printf("Input rows: ");
scanf ("%d", &row);
printf("Input columns: ");
scanf ("%d", &col);
printf ("Input data: \n");
ins(mat, row, col);
printf ("You entered: ");
print(mat, row, col);
return 0;
}
void ins (int *matrix, int row, int column);
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
printf ("Row %d column %d: ", i+1, j+1);
scanf ("%d", &matrix[i][j]);
}
}
}
void print (int *matrix, int row, int column)
{
int i;
int j;
for(i=0; i<row; i++)
{
for(j=0; j<column; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
You need to pass a pointer with as much levels of indirection (*) as the number of dimensions of your matrix.
For example, if your matrix is 2D (e.g. 10 by 100), then:
void ins (int **matrix, int row, int column);
If you have a fixed dimension (e.g. 100), you can also do:
void ins (int (*matrix)[100], int row, int column);
or in your case:
void ins (int (*matrix)[SIZE], int row, int column);
If both your dimensions are fixed:
void ins (int matrix[10][100], int row, int column);
or in your case:
void ins (int matrix[SIZE][SIZE], int row, int column);
If you have a modern C compiler you can do the following for 2D matrices of any sizes
void ins (size_t rows, size_t columns, int matrix[rows][columns]);
Important is that the sizes come before the matrix, such that they are known, there.
Inside your function you then can access the elements easily as matrix[i][j] and the compiler is doing all the index calculations for you.
it would also possible to leave the first dimension empty, the same as (*matrix):
void ins (int matrix[][100], int row, int column);
Much better way to use malloc function and create dynamically allocated array and do whatever you want to do using 2d array:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
void fun(int **arr,int m,int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &arr[i][j]);
}
}
}
int main()
{
int i,j,m,n;
printf("enter order of matrix(m*n)");
scanf("%d*%d",&m,&n);
int **a=(int **)malloc(m*sizeof(int));
for(i=0;i<n;i++)
a[i]=(int *)malloc(n*sizeof(int));
fun(a,m,n);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
output:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
void fun(int **arr,int m,int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &arr[i][j]);
}
}
}
int main()
{
int i,j,m,n;
printf("enter order of matrix(m*n)");
scanf("%d*%d",&m,&n);
int **a=(int **)malloc(m*sizeof(int));
for(i=0;i<n;i++)
a[i]=(int *)malloc(n*sizeof(int));
fun(a,m,n);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
You can try this as well:
void inputmat(int r,int c,int arr[r * sizeof(int)][c * sizeof(int)])

Resources