Segmentation fault while deleting jagged array - c

I'm trying to free a jagged array after making it, but I am encountering an issue with a segmentation fault as I try to delete it:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int *col;
int **row;
//Declare and fill col array
col = malloc(argc * sizeof (int));
for (int k = 1; k < argc; k++) {
col[k] = atoi(argv[k]);
}
row = malloc(argc * sizeof (int*));
//build the ragged array
for (int i = 0; i < argc; i++) {
row[i] = malloc(sizeof (int) * col[i]);
for (int j = 0; j < col[i]; j++) {
row[i][j] = 1;
}
}
//trying to delete it but its not working
for (int i = 0; i < argc; i++) {
for (int j = 0; j < col[i]; j++) {
int* currentIntPtr = row[i];
free(currentIntPtr);
}
}
free(row);
return 0;
}
Compiler message:
Segmentation fault (core dumped)

row = malloc(argc * sizeof (int));
This should be changed to:
row = malloc(argc * sizeof (int *));
As you are allocating a new integer array for each element in "row" and therefore, each element in "row" must be an integer pointer so that it holds the address which points to an array of integers.
Moreover, you are freeing memory in a wrong way.
for (int i = 0; i < argc; i++) {
for (int j = 0; j < col[i]; j++) {
int* currentIntPtr = row[i][j];
free(currentIntPtr);
}
}
This piece of code won't work:.
int* currentIntPtr = row[i][j];
the type of row[i][j] is integer type and you are and you are assigning it to an integer pointer. What this will do is rather than freeing row[i][j] it will take the value of row[i][j] try to free that address which may be out of address space of the program and hence is not allowed and hence the segmentation fault.
The appropriate which would work will be:
for (int i = 0; i < argc; i++) {
int* currentIntPtr = row[i];
free(currentIntPtr);
}

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

Dynamically allocate 2D char array, and create a copy of itself

I have to dynamically allocate a 2d char array where the number of columns and lines are given by the user. After that, I need to create a copy of that 2d char array so I can manipulate its data.
This is how I tried it. When I try to print the copy array, it prints ok, but it gives me a Segmentation fault (core dumped) error. Not sure what I have to do here.
char **original;
original = malloc(sizeof(char *) * lines);
int i, j;
for (i = 0; i < columns; i++)
{
original[i] = malloc(sizeof(char) * columns+ 1);
}
for (i = 0; i < lines; i++)
{
for (j = 0; j < columns; j++)
{
scanf(" %c", &original[i][j]);
}
}
//The following happens inside a different function. The original matrix was passed as a parameter.
char **copy = NULL ;
for (i = 0; i < lines; i++)
{
copy[i] = malloc(sizeof(char) * columns+ 1);
}
for (i = 0; i < lines; i++)
{
strcpy(copy[i],original[i]);
}
The first for is not correct you should do it on lines not column.
You can also copy with memcpy. or copy char by char.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char **original;
int lines = 3;
int columns = 2;
original = malloc(sizeof(char *) * lines);
int i, j;
for (i = 0; i < lines; i++)
{
original[i] = malloc(sizeof(char) * columns);
}
for (i = 0; i < lines; i++)
{
for (j = 0; j < columns; j++)
{
scanf(" %c", &original[i][j]);
}
}
//The following happens inside a different function. The original matriz was passed as a parameter.
char **copy = malloc(sizeof(char *) * lines);
for (i = 0; i < lines; i++)
{
copy[i] = malloc(sizeof(char) * columns);
}
for (i = 0; i < lines; i++)
{
for (j = 0; j < columns; j++) {
copy[i][j] = original[i][j];
}
}
return 0;
}

Re loading integers into an array

The code below works fine when M <= 4, but seems to bugger up if you put in a whole number that's any bigger (in this case, I actually need M to be 10). Does anyone know why this is happening and what can be done about it? Thanks.
/*
"Read all 100 numbers from the text file and store it in a 10x10 array."
*/
#include <stdio.h>
#include <stdlib.h>
FILE *fptr;
int n;
int M = 4; // Length and width of array
int main()
{
// Allocating memory
int **myArray = (int **)malloc(M * sizeof(int));
for (int j = 0; j < M; j++) {
myArray[j] = (int *)malloc(M * sizeof(int));
}
// Loading data into array
fptr = fopen("List of Numbers.txt","r");
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
fscanf(fptr,"%d",&n);
// printf("%d ",n);
myArray[i][j] = n;
}
}
fclose(fptr);
// Printing
for (int i = 0; i < M; i++) {
for(int j = 0; j < M; j++) {
printf("%d ",myArray[i][j]);
}
printf("\n");
}
return 0;
}
This line:
int **myArray = (int **)malloc(M * sizeof(int));
should be:
int **myArray = (int **)malloc(M * sizeof(int *));
^
You are allocating an array of pointers, not an array of ints.

C Language, dynamic 3d array

I have to create a dynamic and 3 dimensional integer-Array in C.
But I have to create the pointers separately and use malloc. I know how to create 2d Array with malloc but I get confused using the following method, and i couldn't really find other question similar to this.
2x2x2 Integer-Array
First step:
int *firstD;
firstD = (int) malloc(2*sizeof(int));
Second step:
int *secondD;
secondD = (int) malloc(2 * firstD * sizeof(int));
Third step:
int *thirdD;
thirdD = (int) malloc(2 * secondD * sizeof(int));
I think maybe I have to add pointers in the starting (int*) and increase it every stepp by one more pointer?
Allocate an array to store pointers to arrays of row pointers.
Allocate arrays to store row pointers.
Allocate arrays to store each rows.
#include <stdlib.h>
int main(void) {
int size1 = 2, size2 = 2, size3 = 2;
int*** array;
array = malloc(sizeof(int**) * size1); // 1
for (int i = 0; i < size1; i++) {
array[i] = malloc(sizeof(int*) * size2); // 2
for (int j = 0; j < size2; j++) {
array[i][j] = malloc(sizeof(int) * size3); // 3
}
}
// free arrays
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
free(array[i][j]);
}
free(array[i]);
}
free(array);
return 0;
}
I wrote type names explicitly in the above example, but I suggest using dereferencing to obtain size of elements to allocate is better to prevent causing typos.
#include <stdlib.h>
int main(void) {
int size1 = 2, size2 = 2, size3 = 2;
int*** array;
// allocate arrays
array = malloc(sizeof(*array) * size1); // 1
for (int i = 0; i < size1; i++) {
array[i] = malloc(sizeof(*array[i]) * size2); // 2
for (int j = 0; j < size2; j++) {
array[i][j] = malloc(sizeof(*array[i][j]) * size3); // 3
}
}
// free arrays
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
free(array[i][j]);
}
free(array[i]);
}
free(array);
return 0;
}
Onitted in the above examples to make them simple, but you should check results of malloc() to see if the allocations are successful.

int** matrix segmentation fault

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

Resources