int** matrix segmentation fault - c

I am trying to pass a matrix by reference and then initialize it dynamically. This is just an example:
int main(int argc, char* argv[]) {
int** matrix = NULL;
initialize(&matrix, 8);
return 0;
}
void initialize(int*** matrix, int size) {
*matrix = (int**) calloc(size, sizeof(int*));
for (int i = 0; i < size; ++i) {
*matrix[i] = (int*) calloc(size, sizeof(int)); // cashes here with segmentation fault
}
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
*matrix[i][j] = 5; // some number, doesn't matter for now
}
}
}
I have also tried the alternative, saving the matrix in a contiguous memory space:
*matrix = (int**) calloc(size, sizeof(int*));
*matrix[0] = (int*) calloc(size * size, sizeof(int));
for (int i = 1; i < size; ++i) {
*matrix[i] = *matrix[0] + size * i; // crashes here, segmentation fault
}
Yet the same error pops. Never on index 0, always on index 1. I don't understand, what am I doing wrong?
Any kind of help will be greatly appreciated!
Kind regards,
Raul.

*matrix[i] = (int*) calloc(size, sizeof(int));
is interpreted as:
*(matrix[i]) = (int*) calloc(size, sizeof(int));
That's why you are seeing segmentation fault.
Use:
(*matrix)[i] = (int*) calloc(size, sizeof(int));
You have a similar error in the line:
*matrix[i][j] = 5;
That should be:
(*matrix)[i][j] = 5;
You can avoid some of the confusion by using a temporary variable in the function.
void initialize(int*** matrix, int size) {
int** m = calloc(size, sizeof(int*));
for (int i = 0; i < size; ++i) {
m[i] = calloc(size, sizeof(int));
}
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
m[i][j] = 5; // some number, doesn't matter for now
}
}
*matrix = m;
}

Related

Not sure why I am getting a segmentation fault

#include <stdio.h>
#include <stdlib.h>
int ** zeros(int rows, int cols) {
int ** array;
array = (int **)malloc(rows * sizeof(int));
for (int i = 0; i < rows;i++) {
array[i] = (int *)malloc(cols * sizeof(int));
}
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
array[r][c] = 0;
}
}
return array;
}
int main(void) {
// declare variables
int rows = 3;
int cols = 3;
int ** zeroArray = zeros(rows, cols);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("%d ",zeroArray[r][c]);
}
printf("\n");
}
return 0;
}
I have this code and when the value of rows is greater than 4 I get a segmentation fault. cols can be anything and it works, I've tested where the pointers are adressed to and everything seems fine but it just breaks when rows is 5 or more.
This:
array = (int **)malloc(rows * sizeof(int));
for (int i = 0; i < rows;i++) {
array[i] = (int *)malloc(cols * sizeof(int));
}
is wrong, it assumes sizeof(int) to be equal to sizeof (int *) which is not a good move on modern systems.
Make it:
array = malloc(rows * sizeof *array);
that removes the manual "guessed" type, and simply uses the size of whatever array points at, which is of course int *.

Memory Read Exception when working with 3D-Array in C

Even though I looked through stackoverflow for this issue for a bit, I couldnt figure out how to solve my problem. I know this a very primitive problem and there are many solutions for similar problems but they didnt help to find a solution.
Its fairly simple:
I allocate a three-dimensional array dynamiclly and the I store the number 2 in each field.
But VS gives me an access-violation.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
int main() {
int width = 512;
int height = 512;
int ***colors = (int ***)malloc(width * sizeof(int **));
for (int i = 0; i < height; ++i) {
colors[i] = (int **)malloc(height * sizeof(int *));
for (int j = 0; j < 3; ++j) {
colors[i][j] = (int *)malloc(3 * sizeof(int));
}
}
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
for (int z = 0; z < 3; z++)
colors[x][y][z] = 2; //Memory Access Violation happens here
free(colors);
return EXIT_SUCCESS;
}
You got confused with index range for for loops.
That is you are not properly allocating the memory thus you will end up accessing out of bound while using it.
for (int i = 0; i < height; ++i) {
colors[i] = (int **)malloc(height * sizeof(int *));
for (int j = 0; j < 3; ++j) {
colors[i][j] = (int *)malloc(3 * sizeof(int));
}
}
should be
for (int i = 0; i < width; ++i) {
colors[i] = (int **)malloc(height * sizeof(int *));
for (int j = 0; j < height; ++j) {
colors[i][j] = (int *)malloc(3 * sizeof(int));
}
}

Getting a segmentation fault on setting value for 2d array, even though for loop counter values are inside the sizeof of array

I am declaring and printing a simple 2d array or matrix.
I am getting a segmentation fault that is being caused by the nested for loop that sets the values of the matrix.
int rows, columns;
rows = columns = 3;
int **matrix;
matrix = malloc(sizeof(int) * rows);
for (int i = 0; i < columns; i++) {
matrix[i] = malloc(sizeof(int) * columns);
}
This throws a seg fault
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
matrix[i][j] = 1;
}
}
If I set i = 1, there is no seg. fault.
for (int i = 1; i < rows; i++) {
for (int j = 0; j < columns; j++) {
matrix[i][j] = 1;
}
}
However, it does make the first 3 values printed random though.
-------
Entire Code
int main(int argc, char const *argv[]) {
int rows, columns;
rows = 3;
columns = 3;
int **matrix;
matrix = malloc(sizeof(int) * rows);
for (int i = 0; i < columns; i++) {
matrix[i] = malloc(sizeof(int) * columns);
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
matrix[i][j] = 1;
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
matrix[i][j] = 1;
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
printf("%d\n", matrix[i][j]);
}
}
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
return 1;
}
Your problem is here:
int **matrix;
matrix = malloc(sizeof(int) * rows);
You want matrix to be an array of pointers to int but you use "sizeof int" instead of "sizeof int pointer". Try:
int **matrix;
matrix = malloc(sizeof(int*) * rows);
or better
int **matrix;
matrix = malloc(rows * sizeof *matrix);
As pointed out by #n.m in a comment, the following:
for (int i = 0; i < columns; i++) {
matrix[i] = malloc(sizeof(int) * columns);
}
is wrong. It shall be:
for (int i = 0; i < rows; i++) { // Notice this change
matrix[i] = malloc(sizeof(int) * columns);
}

why does realloc throws me "Segmentation fault (core dumped)"

I am really new to C and this is for a school assignment.
So, I am tasked to transpose a given matrix.
My current function is the following:
void matrixTranspose(int rows, int cols, int **array) {
int temp[rows][cols];
int i, j;
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
temp[i][j] = array[i][j];
}
}
array = realloc(array, cols * sizeof(int *));
for (i = 0; i < cols; i++) {
array[i] = realloc(array[i], rows * sizeof(int));
}
for (i = 0; i < cols; i++) {
for(j = 0; j < rows; j++) {
array[i][j] = temp[j][i];
}
}
}
If I introduce equal values for columns and rows or if the value of rows is bigger than the value of columns it works fine, but for some reason when the value of rows is smaller than the value of columns, it does not works. (Throws me "Segmentation fault (core dumped)" error).
My main looks like this:
int main() {
int **mat;
int cols, rows;
int i, j;
printf("Enter number of rows\n");
scanf("%d", &rows);
printf("Enter number of columns\n");
scanf("%d", &cols);
mat = (int **) malloc (sizeof(int *) * rows);
for (i = 0; i < rows; i++) {
mat[i] = (int *) malloc (sizeof(int) * cols);
}
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
mat[i][j] = rand() % 10;
}
}
printf("\nBefore transpose: \n");
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
matrixTranspose(rows, cols, mat);
printf("\nAfter transpose: \n");
for (i = 0; i < cols; i++) {
for(j = 0; j < rows; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
I hope I explained myselft correctly, sorry for my english, it is not my first language. Thanks
When you modify array in matrixTranspose, you're changing a local variable. That change isn't visible in the calling function, so mat in main no longer points to valid memory.
You need to change the function to accept address of a int ** and dereference it as needed.
void matrixTranspose(int rows, int cols, int ***array) {
int temp[rows][cols];
int i, j;
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
temp[i][j] = (*array)[i][j];
}
}
*array = realloc(*array, cols * sizeof(int *));
if (!*array) {
perror("realloc failed");
exit(1);
}
int min = rows < cols ? rows : cols;
for (i = 0; i < min; i++) {
(*array)[i] = realloc((*array)[i], rows * sizeof(int));
if (!(*array)[i]) {
perror("realloc failed");
exit(1);
}
}
if (rows > cols) {
for (i = min; i < rows; i++) {
free((*array)[i]);
}
} else if (cols > rows) {
for (i = min; i < cols; i++) {
(*array)[i] = malloc(rows * sizeof(int));
if (!(*array)[i]) {
perror("malloc failed");
exit(1);
}
}
}
for (i = 0; i < cols; i++) {
for(j = 0; j < rows; j++) {
(*array)[i][j] = temp[j][i];
}
}
}
Note that if the number of rows and columns are not the same, you'll need to either free the extra rows you no longer have or use malloc to allocate new rows.
Note also that you should be checking the return value of malloc and realloc for failure.
Then pass the address of mat to this function:
matrixTranspose(rows, cols, &mat);
You can change the transpose function like this:
int ** matrixTranspose(int rows, int cols, int **array) {
...
return array;
}
And then in main call it like this:
mat = matrixTranspose(rows, cols, mat);
Apart from that, I recommend these thanges. I have changed the argument to sizeof to be the actual variable instead of the type.
array = realloc(array, cols * sizeof(*array));
for (i = 0; i < cols; i++) {
array[i] = realloc(array[i], rows * sizeof(*array[0]));
}
and
mat = (int **) malloc (sizeof(*mat) * rows);
for (i = 0; i < rows; i++) {
mat[i] = (int *) malloc (sizeof(*mat[0]) * cols);
}
Your array is passed by value (i.e. you don't pass a pointer to your matrix). Yet you change it.
array = realloc(array, cols * sizeof(int *));
This is just a local change. Also,
for (i = 0; i < cols; i++) {
array[i] = realloc(array[i], rows * sizeof(int));
}
If rows < col this piece of code will try to reallocate memory for array[i] where i>rows-1. That implies deallocating the memory pointed to by array[i] has never been allocated and you have no idea where it points to.
I am tasked to transpose a given matrix.
Key problem: Code passed the pointer by value and matrixTranspose() need to receive its address in order to modify it. Well answered by others without changing much.
Yet consider a larger change instead. Do not modify the original matrix, make a transposed copy and free matrix helper functions.
int **matrixTranspose_copy(int rows, int cols, const int **array) {
int **transpose = malloc(sizeof *transpose * cols);
for (int r = 0; r < cols; r++) {
transpose[r] = malloc(sizeof *transpose[r] * rows);
for(int c = 0; c < rows; c++) {
transpose[r][c] = array[c][r];
}
}
}
return transpose;
}
void matrixFree(int rows, const int **array) {
for (int r = 0; r < rows; r++) {
free(array[r]);
}
free(array);
}
void matrixTranspose_inplace(int rows, int cols, int ***array) {
int **original = *array;
*array = matrixTranspose_copy(rows, cols, original);
matrixFree(original);
}

Segmentation fault, 2-Dimensional Matrix, malloc

I'm trying to create a 2-Dimensional array using malloc.
My code seems correct but when I try to set values, I receive "Segmentation Fault" message.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i, j;
int **m = (int **) malloc(5 * sizeof(int));
if(m == NULL){
printf("Error");
getchar();
exit(-1);
}
for(i = 0; i < 5; i++){
m[i] = (int *) malloc(5 * sizeof(int));
if(m[i] == NULL){
printf("Error");
getchar();
exit(-1);
}
}
for(i = 0; i < 5; i++){
for(j = 0; j < 5; j++){
printf("%d %d\n", i, j);
m[i][j] = 0;
}
}
for(i = 0; i < 5; i++){
for(j = 0; j < 5; j++){
printf("%d ", m[i][j]);
}
printf("\n");
}
}
Thanks.
Change
int **m = (int **) malloc(5 * sizeof(int));
to
//---------------------------------------v
int **m = (int **) malloc(5 * sizeof(int *));
Your code will fail where size of int is not equal to size of pointer variable.
some systems might have pointer size not equal to size of int. In your case your assuming that pointer is of size int
int **m = (int **) malloc(5 * sizeof(int));
change it to
int **m = malloc(5 * sizeof(int *));
always free memory after use. it will lead to memory leak.
Also don't cast when using malloc Check here

Resources