C ++链表中的内存损坏

时间:2014-12-21 21:08:36

标签: c++ memory-leaks linked-list valgrind heap-corruption

我编写了一个简单的C ++应用程序,它只是从stdin读取行并将它们存储在链表中的堆中。不知道为什么Valgrind滥用此代码段...这是什么"无效的读取"?我错误地以这种方式释放为链表分配的内存吗?

1_9.cpp

#include <iostream>
#include <string>

struct Node {
    std::string str;
    Node* next;
};

int main()
{
    std::string line;
    Node* head = NULL;
    Node* _curr = NULL;
    Node* _new = NULL;

    std::cout << "Ready for reading from stdin..." << std::endl;
    while(std::getline(std::cin, line))
    {
        if (!head)
        {
            head = new Node;
            head->str = line;
            _curr = head;
        }
        else
        {
            _new = new Node;
            _new->str = line;
            _curr->next = _new;
            _curr = _new;
        }
    }

    std::cout << "Reading finished. Here are the results:" << std::endl;
    for (Node* _node = head; _node != NULL; _node = _node->next)
    {
        std::cout << "\t" << _node->str << std::endl;
    }

    std::cout << "Cleaning the memory..." << std::endl;
    for (Node* _node = head; _node != NULL; _node = _node->next)
    {
        std::cout << "\t Deleting:" << _node->str << std::endl;
        delete _node;
    }

    std::cout << "Bye!" << std::endl;
    return 0;
}

1_9.test:

asdfhjkl
ASFF
12324124124
opuoiupoiu
1234

Valgrind的输出:

[vitaly@thermaltake 01]$ valgrind --track-origins=yes --tool=memcheck ./1_9 < 1_9.test 
==4890== Memcheck, a memory error detector
==4890== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4890== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==4890== Command: ./1_9
==4890== 
Ready for reading from stdin...
Reading finished. Here are the results:
    asdfhjkl
    ASFF
    12324124124
    opuoiupoiu
    1234
==4890== Conditional jump or move depends on uninitialised value(s)
==4890==    at 0x400E30: main (in /home/vitaly/prog/study/cpp/01/1_9)
==4890==  Uninitialised value was created by a heap allocation
==4890==    at 0x4C27965: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==4890==    by 0x400D63: main (in /home/vitaly/prog/study/cpp/01/1_9)
==4890== 
Cleaning the memory...
     Deleting: asdfhjkl
==4890== Invalid read of size 8
==4890==    at 0x400EA0: main (in /home/vitaly/prog/study/cpp/01/1_9)
==4890==  Address 0x5a141d8 is 8 bytes inside a block of size 16 free'd
==4890==    at 0x4C28991: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==4890==    by 0x400E9B: main (in /home/vitaly/prog/study/cpp/01/1_9)
==4890== 
     Deleting: ASFF
     Deleting: 12324124124
     Deleting: opuoiupoiu
     Deleting: 1234
Bye!
==4890== 
==4890== HEAP SUMMARY:
==4890==     in use at exit: 0 bytes in 0 blocks
==4890==   total heap usage: 30 allocs, 30 frees, 796 bytes allocated
==4890== 
==4890== All heap blocks were freed -- no leaks are possible
==4890== 
==4890== For counts of detected and suppressed errors, rerun with: -v
==4890== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 2 from 2)

UPD:添加了一些调试输出。无法弄清楚为什么在最后一个循环的第一次迭代中发出invalid read

1 个答案:

答案 0 :(得分:4)

一个猜测是您尝试访问已删除的对象:

for之后的_node = _node->nextdelete node;