user4089193
user4089193

Reputation:

This cpp code below crashes everytime I input a string of length 4 (the malloc in vector fails)

I am using this program to store the values I input in the nxn matrix.

The first input is number of test cases. The second is the value of n. So I create a n*n matrix. Then I input the values for each row Ex: .... The input is always a combination of '.' or '#'.

Here is a part of the code I am using:

#define COL(val, R, C) (R*val)+C ? (R*val)+C:0
int main() {
    // Read the data
    int total_test = 0;
    int tmp, val = 0;
    std::string tmp_s;

    std::cin >> total_test;
    // RUn it total_test number of time
    for (; total_test; total_test--) {
        std::cin >> val;
        matrix path = matrix(val);
        // Parse input
        for (int row = val-1; row >= 0; row--) { //Corrected
            std::cin >> tmp_s;
            std::vector<char> chars(tmp_s.begin(), tmp_s.end());
            for(int col = val-1; col >= 0; col--) {
                if (chars[col] == '#')
                    path.row[row][COL(val, row, col)] = -1; // This is culprit! Thanks @The Dark
            }
        }

    }
    return 0;
}

I run this program and everytime I give the input string to read as "...." this program crashes. I know the exact line where this occurs..

Its either cin >> tmp_s; (I am pretty sure think this is not the line) Its this line: std::vector chars(tmp_s.begin(), tmp_s.end());

The GDB has this to say! Can anyone help me with this? Thanks.

(gdb) s
57              std::cin >> tmp_s;
(gdb) 
....
a.out: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) 

Thanks! :)

Upvotes: 0

Views: 473

Answers (3)

The Dark
The Dark

Reputation: 8514

I think you have edited out the bit that is going wrong from your posted code. Looking at your previous code you have a matrix with a row element that contains an array with pointers to all the rows, so far so good. You also have a col element which has a pointer to all the data (probably should be called data).

However, when you are accessing the data you are using this code:

path.row[row][COL(val, row, col)] = -1;

where COLis

#define COL(val, R, C) (R*val)+C ? (R*val)+C:0

The COL macro is used to calculate the position in the data for a row R and a column C, but your path.row pointer has already pre-calculated the position of the row. This means that for any row other than 0, you will be writing to the wrong spot and any row greater than n/2 will be writing past the end of your array, possibly causing a crash like you are seeing.

To fix this, use the array access that you have set up and don't use the COL macro (you should remove it from your code):

path.row[row][col] = -1;

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385274

tmp_s is empty. Always. But you use it to initialise chars then access elements of chars that consequently do not exist!

Upvotes: 0

UldisK
UldisK

Reputation: 1639

I think, the problem is that you are accessing array out of bounds here:

    for (int row = val; row; row--)

That is corrupting the stack. It should be:

    for (int row = val-1; row>=0; row--)

Other thing is: you should better use std::getline instead of std::cin >> tmp_s and check the input.

Finally, you don't need to allocate 2 arrays in matrix: allocate one with size val*val and add an at(int row,int col) function, that calculates offset as row*row_size+col. It will be faster then 2 pointer access.

Upvotes: 2

Related Questions