0

I've written a program which compiles and runs well on my 64-bit machine (running linux SUSE). Now I need to call an external library but I only have access to the 32-bit binary. My source code compiles and links with no errors from ssh command line to a 32 bit machine, but I get a memory error at runtime now before the library is called, or any of the interesting stuff happens...

I have a simple class cWorld to initialize some other classes, it has a method cWorld::ReadData() which opens a text file and parses/reads lines from the file and stores values in various members of cWorld, and then closes the file. The file, input.txt, just holds some explanation text and initial condition values, separated by commas and semicolons. Nothing groundbreaking!

Debugging with gdb showed that the file opens, closes successfully, all the data is stored successfully, then the SIGABRT is thrown at the very end when the ReadData() method is exited.

Extracted the problem code from my program:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>


class cWorld {
    public:
        cWorld ();
        void CallReadData ();
    private:
        int N_target, N_steps;
        double t0, tf, delt;
        std::vector<double> data;
        void ReadData ();
};


cWorld::cWorld () {
    N_target = 0;
    N_steps = 0;
    delt = 0.0;
    t0 = 0.0;
    tf = 0.0;
}

void cWorld::CallReadData() {
    ReadData();
}


void cWorld::ReadData() {
    std::string line;
    std::ifstream input("input_test.txt");

    if (input.is_open()) {

         // RETRIEVE INPUT OPTIMIZATION PARAMETERS

        input.ignore(1000, '>');              // ignore text until first '>' appears
        std::getline(input, line, ';');       // get int N_target
        std::stringstream(line) >> N_target;

        input.ignore(1000, '>');              // ignore text until first '>' appears
        std::getline(input, line, ',');       // get t0
        std::stringstream(line) >> t0;

        std::getline(input, line, ',');       // get delt
        std::stringstream(line) >> delt;
        std::cout << "delt = " << delt << std::endl;

        std::getline(input, line, ',');       // get tf
        std::stringstream(line) >> tf;

        N_steps = (int)( (tf - t0) / delt ) + 1;   // set an int cWorld::N_steps

        // RETRIEVE INPUT STATE PARAMETERS

        int index = 0;                       // initialize local iterator
        data.resize(12*N_target, 0.0);       // set data size
        std::cout << "data elements = " << data.size() << std::endl;

        while (!input.eof()) {

            // if there's '<' end loop
            if (input.peek() == '<') break;

            // if there's a semicolon, store following text in data...
            else if (input.peek() == ';') {
                input.ignore(1000, '>');
                std::getline(input, line, ',');
                std::stringstream(line) >> data[index];
                index++;
            }

            // else if there's a comma, store following text in data...
            else {
                std::getline(input, line, ',');
                std::stringstream(line) >> data[index];
                index++;
            }

        }

        input.close();

    }

    else  std::cout << "Can't open file 'input.txt'.\n";
}




int main() {

    cWorld world_1;
    world_1.CallReadData();

    return 0;

}

input text file:

/****************************************************************/
/*                                                              */
/*  p2pOpt.C INPUT FILE                                         */
/*                                                              */
/****************************************************************/

System Parameters: number of paths to optimize
format: N_target; (int)


>3;


System Parameters: start time, step size, end time
format: t0,delt,tf,; (doubles)


>0.0,0.001,1,;


Target 1 Parameters: Initial Conditions
format: x,y,z,theta1,theta2,theta3,xdot,ydot,zdot,theta1dot,theta2dot,theta3dot,;(doubles)

>1.0,0.0,0.0,3.14159265359,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,;
>2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,;
>3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,;
<

Here's the debug output:

======= Memory map: ========
08048000-0804b000 r-xp 00000000 00:29 18254842   /home/ston_sa/core/motion_planning/algorithms_cpp/p2pOpt/test_3_32
0804b000-0804c000 r--p 00002000 00:29 18254842   /home/ston_sa/core/motion_planning/algorithms_cpp/p2pOpt/test_3_32
0804c000-0804d000 rw-p 00003000 00:29 18254842   /home/ston_sa/core/motion_planning    /algorithms_cpp/p2pOpt/test_3_32
0804d000-0806e000 rw-p 00000000 00:00 0          [heap]
b7b00000-b7b21000 rw-p 00000000 00:00 0
b7b21000-b7c00000 ---p 00000000 00:00 0
b7cd8000-b7cdb000 rw-p 00000000 00:00 0
b7cdb000-b7e42000 r-xp 00000000 08:06 114523898  /lib/libc-2.11.3.so
b7e42000-b7e44000 r--p 00167000 08:06 114523898  /lib/libc-2.11.3.so
b7e44000-b7e45000 rw-p 00169000 08:06 114523898  /lib/libc-2.11.3.so
b7e45000-b7e48000 rw-p 00000000 00:00 0
b7e48000-b7e64000 r-xp 00000000 08:06 114544736  /lib/libgcc_s.so.1
b7e64000-b7e65000 r--p 0001b000 08:06 114544736  /lib/libgcc_s.so.1
b7e65000-b7e66000 rw-p 0001c000 08:06 114544736  /lib/libgcc_s.so.1
b7e66000-b7e8c000 r-xp 00000000 08:06 114353773  /lib/libm-2.11.3.so
b7e8c000-b7e8d000 r--p 00026000 08:06 114353773  /lib/libm-2.11.3.so
b7e8d000-b7e8e000 rw-p 00027000 08:06 114353773  /lib/libm-2.11.3.so
b7e8e000-b7f70000 r-xp 00000000 08:06 2169219    /usr/lib/libstdc++.so.6.0.16
b7f70000-b7f74000 r--p 000e2000 08:06 2169219    /usr/lib/libstdc++.so.6.0.16
b7f74000-b7f75000 rw-p 000e6000 08:06 2169219    /usr/lib/libstdc++.so.6.0.16
b7f75000-b7f7c000 rw-p 00000000 00:00 0
b7fdd000-b7fdf000 rw-p 00000000 00:00 0
b7fdf000-b7ffe000 r-xp 00000000 08:06 114544574  /lib/ld-2.11.3.so
b7ffe000-b7fff000 r--p 0001e000 08:06 114544574  /lib/ld-2.11.3.so
b7fff000-b8000000 rw-p 0001f000 08:06 114544574  /lib/ld-2.11.3.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

Program received signal SIGABRT, Aborted.
0xffffe424 in __kernel_vsyscall ()

and backtrace:

#0  0xffffe424 in __kernel_vsyscall ()
#1  0xb7d05e20 in raise () from /lib/libc.so.6
#2  0xb7d07755 in abort () from /lib/libc.so.6
#3  0xb7d44d65 in __libc_message () from /lib/libc.so.6
#4  0xb7d4ac54 in malloc_printerr () from /lib/libc.so.6
#5  0xb7d4c563 in _int_free () from /lib/libc.so.6
#6  0xb7d4f69d in free () from /lib/libc.so.6
#7  0xb7f3fa0f in operator delete(void*) () from /usr/lib/libstdc++.so.6
#8  0xb7f26f6b in std::string::_Rep::_M_destroy(std::allocator<char> const&) () from /usr/lib/libstdc++.so.6
#9  0xb7f26fac in ?? () from /usr/lib/libstdc++.so.6
#10 0xb7f2701e in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/libstdc++.so.6
#11 0x080495bf in cWorld::ReadData (this=0xbfffefe0) at test_3.cpp:91
#12 0x0804961b in cWorld::CallReadData (this=0xbfffefe0) at test_3.cpp:30
#13 0x08049646 in main () at test_3.cpp:100

at #11 test_3.cpp:91 is the closing bracket of the ReadData() method.

2 Answers2

0

First note, you didn't include a sample input.txt to test against. Second note, what are some sample values the variables are initialized to?

So, given that tf=0.0, t0=0.0, and delt=1.0 and using an input.txt of:

>
1;
1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0
<

I get an a vector of data with 11 entries, with the first 11 values in the list and no errors. Are you sure your input.txt is formatted as the code expects? Do you really want to delete the last item in the list?

JonS
  • 621
  • 7
  • 25
  • would +1 you if I could for asking about initialization. I don't *think* this is the problem because I have a constructor `cWorld()` which initializes all the members (except std::vector data) to zeros... –  Jul 16 '13 at 08:39
  • I updated the question to show an example of 'input.txt' and the whole problem code, extracted from my program. When I compile this exact code in 32bit and run with this exact `input.txt` the error occurs. I would believe it's something stupid with the text file, because if I make any slight changes to the format, `ReadData()` iterates through the while loop too many times (or not enough times) and goes out of the memory block allocated to `data`. It's just so strange because it works fine in 64 bit but not in 32... –  Jul 16 '13 at 10:02
  • With your input file, I get your error, but I get the message that it's a problem with a double deallocation of std::basic_string. I think your read function is overly complicated, but the text file format is showing up a basic problem with it. – JonS Jul 16 '13 at 20:26
0

Your first problem is that your loop does 37 reads but only resizes data to be 36 elements. You should restructure how you are parsing your input. Maybe use scanf() if nothing else.

JonS
  • 621
  • 7
  • 25