首页 > 解决方案 > istringstream 上的双重释放或损坏(输出)

问题描述

我正在尝试重播 SNIA FIU 跟踪。每行记录如下: [seq num] [ts in ns] [operation] [inode num] [inode size in Bytes] [offset in Bytes] [size in Bytes] [HIT, MISS or APPEND]

我想得到一个操作,inode num,offset。我按如下方式实现(ifs 是跟踪文件的输入文件流)。

    uint64_t* keys = (uint64_t*)malloc(sizeof(uint64_t)*numData);
    uint8_t* ops = (uint8_t*)malloc(sizeof(uint8_t)*numData);

    ifstream ifs;
    ifs.open(data_path);
    if(!ifs){
        cerr << "no file" << endl;
        return 0;
    }

    dprintf("[ INFO ] %s is used\n", data_path);
    char tmp[100];
    for(unsigned int i=0; i<numData; ){
        string word; // for storing each word
        uint8_t op;
        uint64_t key;
        unsigned int index = 0;
        unsigned int batch = 0;

        ifs.getline(tmp, 100);
        string stmp(tmp);

        // Used to split string around spaces.
        istringstream ss(stmp);

        // Traverse through all words
        // while loop till we get
        // strings to store in string word
        while (ss >> word)
        {
            // operation
            if (index == 2) {
                if ( word == "READ" ) {
                    op = 1;
                } else if (word == "WRITE") {
                    op = 2;
                } else {
                    break;
                }
            } else if (index == 3) {
                // inode number
                key = stoul(word);
                key <<= 32;
            } else if (index == 5) {
                // pageoff
                key += stoul(word);
            } else if (index == 6) {
                // size -> batch
                batch = stoul(word) / 4096 + (stoul(word) % 4096 ? 1 : 0);
            } else if (index == 7) {
                // page cache hit
                if (word == "HIT") {
                    batch = 0;
                    break;
                }
            }

            index++;
        }

        // processing batch
        for ( unsigned int b = 0 ; b < batch ; b++) {
            ops[i + b] = op;
            keys[i + b] = key + 4096 * b;
        }
        i += batch;
    }

我认为它的逻辑是正确的,但是我收到了我无法弄清楚的错误消息。

这是带有堆栈帧的错误消息。

double free or corruption (out)

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff70598b1 in __GI_abort () at abort.c:79
#2  0x00007ffff70a2907 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff71cfdfa "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff70a997a in malloc_printerr (str=str@entry=0x7ffff71d1ad0 "double free or corruption (out)") at malloc.c:5350
#4  0x00007ffff70b0ee5 in _int_free (have_lock=0, p=0x55555579cbe0, av=0x7ffff7404c40 <main_arena>) at malloc.c:4278
#5  __GI___libc_free (mem=0x55555579cbf0) at malloc.c:3124
#6  0x00007ffff7739c3b in std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_istringstream() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00005555555597da in main (argc=10, argv=0x7fffffffe0f8) at replay_KV.cpp:197
(gdb) f 7
#7  0x00005555555597da in main (argc=10, argv=0x7fffffffe0f8) at replay_KV.cpp:197
warning: Source file is more recent than executable.
197                     // Traverse through all words
(gdb) l
192                     string stmp(tmp);
193
194                     // Used to split string around spaces.
195                     istringstream ss(stmp);
196
197                     // Traverse through all words
198                     // while loop till we get
199                     // strings to store in string word
200                     while (ss >> word)
201                     {
(gdb)

我没有使用多线程。

标签: c++

解决方案


推荐阅读