0
I am trying to dynamically allocate a 2D array to store a bmp file with the following code:
#include <stdio.h>
#include <stdlib.h>
int height, width; // variables for the image height and width
int** storeImage (FILE* fil) { // function that reads and stores the image in a matrix
int** img;
char* trash = malloc(255 * sizeof(char));
fscanf (fil, "%s", trash);
free(trash);
fscanf (fil, "%d", &width);
fscanf (fil, "%d", &height);
img = malloc (height * sizeof(int*));
for (int i = 0; i < height; i++) {
img[i] = malloc (width * sizeof(int));
}
fscanf (fil, "%d", &img[0][0]);
for (int i = 0; i < height; i++) { // for that fills the matrix img
for (int j = 0; j < width; j++) {
fscanf (fil, "%d", &img[i][j]);
}
}
return img;
}
int main (void) {
char* file_name = malloc(255 * sizeof(char));
scanf("%[^\n]s", file_name);
getc(stdin); // consumes the '\n' or '\r'
FILE* fil = NULL;
fil = fopen(file_name, "r");
int** img = storeImage(fil); // pointer to the matrix that represents the image
fclose(fil);
for (int i = 0; i < height; i++) { // for that prints the matrix img
for (int j = 0; j < width; j++) {
printf("%d ", img[i][j]);
}
printf("\n");
}
for (int i = 0; i < height; i++) {
free(img[i]);
}
free (img);
free (file_name);
return 0;
}
The file I am reading has the following format:
P2
5 6
255
10 13 18 12 11
11 10 17 10 19
16 17 19 11 12
18 18 17 16 17
13 12 19 13 15
16 10 11 19 14
At first, the program works and prints what I want in the terminal. However, when I run it on Valgrind, I get a Segmentation fault (core dumped):
==8965== Syscall param openat(filename) points to uninitialised byte(s)
==8965== at 0x4B0E0EE: open (in /usr/lib/libc-2.26.so)
==8965== by 0x4AA0CE2: _IO_file_open (in /usr/lib/libc-2.26.so)
==8965== by 0x4AA0EB1: _IO_file_fopen@@GLIBC_2.2.5 (in /usr/lib/libc-2.26.so)
==8965== by 0x4A94715: __fopen_internal (in /usr/lib/libc-2.26.so)
==8965== by 0x108AC5: main (in /home/aluno/Projetos/debug)
==8965== Address 0x4dde040 is 0 bytes inside a block of size 255 alloc'd
==8965== at 0x403077F: malloc (vg_replace_malloc.c:299)
==8965== by 0x108A7F: main (in /home/aluno/Projetos/debug)
==8965==
==8965== Invalid read of size 4
==8965== at 0x4A91F4D: __isoc99_fscanf (in /usr/lib/libc-2.26.so)
==8965== by 0x108930: storeImage (in /home/aluno/Projetos/debug)
==8965== by 0x108AD5: main (in /home/aluno/Projetos/debug)
==8965== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8965==
==8965==
==8965== Process terminating with default action of signal 11 (SIGSEGV): dumping
core
==8965== Access not within mapped region at address 0x0
==8965== at 0x4A91F4D: __isoc99_fscanf (in /usr/lib/libc-2.26.so)
==8965== by 0x108930: storeImage (in /home/aluno/Projetos/debug)
==8965== by 0x108AD5: main (in /home/aluno/Projetos/debug)
==8965== If you believe this happened as a result of a stack
==8965== overflow in your program's main thread (unlikely but
==8965== possible), you can try to increase the size of the
==8965== main thread stack using the --main-stacksize= flag.
==8965== The main thread stack size used in this run was 8388608.
==8965==
==8965== HEAP SUMMARY:
==8965== in use at exit: 510 bytes in 2 blocks
==8965== total heap usage: 4 allocs, 2 frees, 2,086 bytes allocated
==8965==
==8965== LEAK SUMMARY:
==8965== definitely lost: 0 bytes in 0 blocks
==8965== indirectly lost: 0 bytes in 0 blocks
==8965== possibly lost: 0 bytes in 0 blocks
==8965== still reachable: 510 bytes in 2 blocks
==8965== suppressed: 0 bytes in 0 blocks
==8965== Reachable blocks (those to which a pointer was found) are not shown.
==8965== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==8965==
==8965== For counts of detected and suppressed errors, rerun with: -v
==8965== Use --track-origins=yes to see where uninitialised values come from
==8965== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
What is the reason for this error?
How is that possible? on my machine I always get that same mistake
– sabonet
And how can I improve the code to make it less confusing?
– sabonet
I also can’t reproduce your problem. Which version of Valgrind are you using? Another possibility is to use the -fsanitize=memory flag in the build of the program to make it insert memory addressing checks.
– MrParrot
@Mrparrot I’m using 3.14.0
– sabonet