-1

I'm trying to read a file into an array but I'm getting segmentation fault, I know I'm not allocating memory correctly. What am I doing wrong here?. I'm allowed to use read() and while loop.

EDIT

my complete function, before I split in into two parts

int     **ft_create_map(char *filename, int nb_cols, int nb_rows)
{
    int     **map;
    int     fd;
    int     row;
    int     col;
    ssize_t size;
    char    buf[BUF_SIZE];

    row = 0;
    size = 0;
    col = 0;
    map = (int **)malloc(nb_rows * sizeof(int *));
    if (!map)
            return (map);
            map[0] = malloc(sizeof(int) * nb_cols);
            fd = open(filename, O_RDONLY);
            if (!fd)
                    return (NULL);
                    while ((size = read(fd, buf, BUF_SIZE)))
                    {
                            if (size < 1)
                                    return (NULL);
                            buf[size] = '\0';
                            if (buf[0] == '\n')
                            {
                                    row += 1;
                                    col = 0;
                                    map[row] = malloc(sizeof(int) * nb_cols);
                            }
                            else
                            {
                                    if (buf[0] == '.')
                                            map[row][col] = 1;
                                    else if (buf[0] == 'o')
                                            map[row][col] = 0;
                                    col++;
                            }
                    }
    return (map);
 }

Here I'm trying to split the previous function into two functions, because my functions needs to have less than 25 lines of code.

void fill_map(int **map,int fd, int row, int col)
{
    ssize_t size;
    char    buf[BUF_SIZE];

    size = 0;
    while ((size = read(fd, buf, BUF_SIZE)))
    {
        if (size < 1)
           // return (0); commented out for testing
        buf[size] = '\0';
        if (buf[0] == '\n')
        {
            //this was the problem, allocating memory to map[0] twice.
            row += 1;
            map[row] = malloc(sizeof(int) * (col + 1));
            col = 0;
        }
        else
       {
           if (buf[0] == '.')
              map[row][col] = 1;
           else if (buf[0] == 'o')
              map[row][col] = 0;
           col++;
       }
    }
 }

 int        **ft_create_map(char *filename, int nb_cols, int nb_rows)
 {
    int     **map;
    int     fd;
    int     row;
    int     col;
    ssize_t size;
    // char buf[BUF_SIZE];

    row = 0;
    size = 0;
    col = 0;
    map = (int **)malloc(nb_rows * sizeof(int *));
    if (!map)
       return (map);
    map[0] = malloc(sizeof(int) * nb_cols);
    fd = open(filename, O_RDONLY);
    if (!fd)
       return (NULL);
    fill_map(map, fd, row, col);
    return (map);
 }

in my main

int cols = count_cols(argv[1]);
int rows = count_rows(argv[1]);
int **arr;
// int  j;
// int i;

arr = ft_create_map(argv[1], cols, rows);
printf_max_square(arr, rows, cols);

code ideone

Junius L
  • 15,881
  • 6
  • 52
  • 96

2 Answers2

3

Assuming this line gets commented in

 // return (0); commented out for testing

the moment read() returns BUF_SIZE, this line

buf[size] = '\0';

writes out of buf's bounds and with this invokes undefined behaviour.

alk
  • 69,737
  • 10
  • 105
  • 255
  • 2
    We don't know what `BUF_SIZE` is (maybe it's 0??), but with the code provided, shouldn't `buf[size] = '\0';` only get executed if size < 1? As soon as `// return (0)` is uncommented out I completely agree with this. – yano Apr 20 '16 at 14:33
  • @yano: Correct, adjusted my answer. However, I know those guys ... ;-) – alk Apr 20 '16 at 14:35
  • the problem is not the `buf[size]`, this doesn't have any effect, I can remove or leave it, the program will still runs. – Junius L Apr 20 '16 at 14:36
  • @Phuti: If it continues running, that's just bad luck. It still might crash two years later ... assuming it ran so long. ;-) – alk Apr 20 '16 at 14:36
  • 2
    @Phuti Well, that's a dangerous game, the whole point is it's UB, so when combined with Murphy's law that means it will _always_ work when you run it for yourself and _never_ work during a demo for your boss/customer or the TA who's grading it. – yano Apr 20 '16 at 14:39
0

It looks like you have a potential memory leak. In ft_create_map you have map[0] = malloc(sizeof(int) * nb_cols); Then in fill_map you have map[row] = malloc(sizeof(int) * (col + 1)); where row==0. So this will be a mem leak if buf[0] == '\n'.

Actually kind of surprised to hear (from the OP) that this is also causing a segfault, but maybe that would become obvious if we knew the exact program flow.

yano
  • 4,827
  • 2
  • 23
  • 35