具有多个对象的手写单链表中的分割错误

时间:2019-02-06 13:45:49

标签: c++ pointers memory fault

我正在处理工作中的自定义书面单链表,其元素是指向对象的智能指针。问题在于,在列表中成功插入一定数量的元素(例如50000)之后, 当列表超出范围时,程序会因分段错误而崩溃,并且元素开始一一(通过智能指针)被破坏。成功创建了50000个元素,但是每次销毁43256(例如)对象时,程序就会崩溃。

注意:处理少量对象-5000、10000、20000 ...时-完全没有问题。

我们使用C ++ 98标准版本和Boost 1.55.0 C ++库。

该程序发生在Red Hat上,但是我也在Ubuntu上本地尝试过-同样。我只是为了实验而尝试的方法是使用std :: list,std :: vector,boost :: container :: slist而不是草稿的单链接列表,问题不再存在。但是我真的很想知道问题出在哪里。

下面是重现该问题的示例代码:

#include <iostream>
#include "boost/lexical_cast.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"
#include <vector>

class SmartInt;
typedef boost::shared_ptr<SmartInt> BoostSharedPtrSmartInt;

class SmartInt
{
public:
    int m_data;
    BoostSharedPtrSmartInt m_ptrNext;

    void SetNext(BoostSharedPtrSmartInt ptrNext)
    {
        m_ptrNext = ptrNext;
    }

    BoostSharedPtrSmartInt GetNext() const
    {
        return m_ptrNext;
    }
};

class IntList
{
public:
    BoostSharedPtrSmartInt m_ptrFirst;
    BoostSharedPtrSmartInt m_ptrLast;

    void AddParameter( BoostSharedPtrSmartInt ptrParam ) throw()
    {
        if( m_ptrFirst == NULL )
        {
            std::cout << "ST_TEST First time AddParameter" << std::endl;
            m_ptrFirst = m_ptrLast = ptrParam;
        }
        else
        {
            m_ptrLast->SetNext( ptrParam );
            m_ptrLast = ptrParam;
        }
    }
};

void test3(int numObjects)
{
    IntList list;
    int i = 1;
    for(; i <= numObjects; ++i)
    {
        BoostSharedPtrSmartInt bspsi = boost::make_shared<SmartInt>();
        list.AddParameter( bspsi );
    }
    std::cout << "ST_TEST i = " << i << std::endl;
    std::cout << "ST_TEST Getting out of scope - everything should get destroyed now!" << std::endl;
}

int main(int argc, char **argv)
{
    if(argc != 2)
    {
        std::cout << "Usage: ./test <number of objects created>" << std::endl;
        exit(1);
    }

    test3( boost::lexical_cast< int >( argv[1] ) );
    return 0;
}

要构建项目,我使用CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.6)
project(test)

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

find_package(Boost REQUIRED)

include_directories(${Boost_INCLUDE_DIRS}) 

add_executable(test main.cpp)

target_link_libraries( test
 ${Boost_LIBRARIES} )

谢谢,我真的很困惑为什么会发生车祸,并且我已经处理了1-2周...

1 个答案:

答案 0 :(得分:2)

您的程序由于Botje的堆栈溢出而崩溃。您可以通过在列表析构函数中明确地释放列表项来避免这种情况。

...
class SmartInt
{
public:
...    
    void Reset() {
        m_ptrNext.reset();
    }
...
};

class IntList
{
public:
...    
    ~IntList() {
        while (m_ptrFirst != m_ptrLast) {
            BoostSharedPtrSmartInt tmp = m_ptrFirst->GetNext();
            m_ptrFirst->Reset();
            m_ptrFirst = tmp;
        }
    }
};
....