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;
}
Related
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.
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);
}
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);
}
I have to read a maze from a file and store it in a twodimensional array.
The characters I'm reading are stored in a .txt file like this:
######
#....#
#..#.#
. .#..
######
Note that the number of rows and columns can vary depending on the file.
My approach in reading the file so far:
#include <stdio.h>
#include <stdlib.h>
void read_arr(char** a, int x_size, int y_size) {
int i, j;
int tmp;
FILE* file = fopen("lab1.txt", "r");
for (i = 0; i < y_size; i++) {
for (j = 0; j < x_size; j++) {
if (tmp = fgetc(file))
a[j][i] = tmp;
printf("Success\n");
}
}
}
void print_arr(char** a, int x_size, int y_size) {
int i, j;
for (i = 0; i < x_size; i++) {
for (j = 0; j < y_size; j++) {
printf("%c", a[i][j]);
}
printf("\n");
}
}
int main() {
int x_size, y_size;
printf("What is the size of the maze (<x> <y>)? ");
scanf("%d %d", &x_size, &y_size);
printf("Maze has size %dx%d\n", x_size, y_size);
char** a = malloc(sizeof(char) * (x_size * y_size));
if (!a)
return -1;
printf("Successfully allocated memory!\n");
read_arr(a, x_size, y_size);
print_arr(a, x_size, y_size);
return 0;
}
But all I get from this is a memory error (I'm afraid I cant't give the exact error message, because it is displayed in german).
Another thing I've tried is using fscanf, but that didn't work either.
I'm on Ubuntu, and using gcc to compile my code.
Any help would be much appreciated!
Memory allocation is not correct
char** a = malloc(sizeof(char) * (x_size * y_size));
I guess what you wanted to do is
char** a = malloc(sizeof(char*) * y_size);
for(i = 0; i < y_size; ++i)
a[i]=malloc(x_size);
Also in read_arr function, you access array as arr[j][i], while j is your inner index, and i is outer
for (i = 0; i < y_size; i++) {
for (j = 0; j < x_size; j++) {
if (tmp = fgetc(file))
a[j][i] = tmp; ==> a[i][j] = tmp;
printf("Success\n");
}
}
I'm creating a dynamic 2d character array in C:
Note: rows and columns are user input integers
char** items;
items = (char**)malloc(rows * sizeof(char*));
int i;
for(i = 0; i < rows; i++)
{
items[i] = (char*)malloc(columns * sizeof(char));
}
int j;
for(i = 0; i < rows; i++)
{
for(j = 0; j < columns; j++)
{
items[i][j] = 'O';
}
}
Later in my code, I attempt to overwrite a specific location in the array:
items[arbitraryRow][arbitraryColumn] = 'S';
But the result is that the characters in that row/column are now 'SO'
What am I doing wrong?
Update:
This is how I'm printing the array:
int i;
for(i = 0; i < rows; i++)
{
printf("[");
int j;
for(j = 0; j < columns; j++)
{
printf("'%s'", &items[i][j]);
if(j != columns - 1)
printf(", ");
}
printf("]");
printf("\n");
}
You're not storing strings you're storing characters so all you can read is one character so that'd be the S
My suspision is that the next character is an O so when you look at it as a string you get SO
printf("'%c'", items[i][j]);
You are storing characters and reading strings. Try reading character back from the Array.
Change your code to:
int i;
for(i = 0; i < rows; i++)
{
printf("[");
int j;
for(j = 0; j < columns; j++)
{
printf("'%c'", items[i][j]);
if(j != columns - 1)
printf(", ");
}
printf("]");
printf("\n");
}