You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用迭代器遍历std::list<Server>时触发Segmentation Fault问题

问题:遍历std::list时触发段错误

尝试用迭代器遍历std::list<Server>时,访问第二个迭代器会触发Segmentation Fault(段错误)。

程序流程:

  • 实例化3个Server对象并设置端口号
  • 通过TcpServer的pushNewServer方法将对象存入私有成员std::list<Server> _servers,该方法实现:
void TcpServer::pushNewServer(const Server& server)
{
    _servers.push_back(server);
};
  • 创建迭代器遍历列表至末尾时触发段错误,完整代码如下:
#include <string>
#include <iostream>
#include <list>

# define GET 1
# define POST 2
# define DELETE 3
# define SET -1
# define CLEAR -2
# define ALL_METHODS 7

#define bitset(byte,nbit)   (byte |= (1 << nbit))
#define bitclear(byte,nbit) (byte &= ~(1 << nbit))
#define bitcheck(byte,nbit) (byte & (1 << nbit))

class Server;
class Location;
class TcpServer
{
    public:
        TcpServer(const std::string& filename){(void)filename;};
        ~TcpServer(){};

        /*GETTERS*/
        std::list<Server> getServers(void) const {return _servers;};

        /*SETTERS*/
        void pushNewServer(const Server& server){_servers.push_back(server);};
    private:
        TcpServer(const TcpServer& rhs);
        TcpServer& operator=(const TcpServer& rhs);
        TcpServer();
        std::list<Server> _servers;
        /* data */
};



class Location
{
    public:
        Location()
            :_location_options(0),_body_size(0),_index(""),_root_dir(""),_uri(""),_server(0){};
        Location(const Location& rhs)
        {
            _location_options = rhs._location_options;
            _body_size = rhs._body_size;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _uri = rhs._uri;
            _sub_locations = rhs._sub_locations;
            _server = rhs._server;
        }
        Location& operator=(const Location& rhs)
        {
            if (this == &rhs) return *this;
            _location_options = rhs._location_options;
            _body_size = rhs._body_size;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _uri = rhs._uri;
            _sub_locations = rhs._sub_locations;
            _server = rhs._server;
            return *this;
        }
        ~Location(){};
    
        /*GETTERS*/
        unsigned int&  getLocationsOptions(void) {return _location_options;};
        const unsigned int& getBodySize(void) const {return _body_size;};
        const std::string& getRootDir(void) const {return _root_dir;};
        const std::string& getIndex(void) const {return _index;};
        const std::string& getUri(void) const {return _uri;};
        std::list<Location> getSubLocations(void) const {return _sub_locations;};
        const Server* getServer(void) const {return _server; };

        /*Setters*/
        void    setBodySize(const unsigned int& body)
        {
            _body_size = body;
        };
        void    setIndex(const std::string& index)
        {
            _index = index;
        };
        void    setRootDir(const std::string& root_dir)
        {
            _root_dir = root_dir;
        };
        void    setUri(const std::string& uri)
        {
            _uri = uri;
        };
        void    pushNewLocation(const Location& location)
        {
            _sub_locations.push_back(location);
        };
        void    setServer(Server *server)
        {
            _server = server;
        };

        void    setLocationOption(const unsigned int& nbit, char actions)
        {
            if (actions == SET)
                bitset(_location_options, nbit);
            else if (actions == CLEAR)
                bitclear(_location_options, nbit);
        };

        /*MEMBER FUNCTION*/
        bool    checkBits(const unsigned int& nbit) const
        {
            return (bitcheck(_location_options, nbit) > 0);
        }
    private:
        unsigned int    _location_options;
        unsigned int    _body_size;
        std::string _index;
        std::string _root_dir;
        std::string _uri;
        std::list<Location> _sub_locations;
        Server  *_server;
};


class Server
{
    public:
        Server()
            :_serv_options(0),_port(0),_body_size(0),_root_dir(""),_index(""){};
        Server(const Server& rhs)
        {
            _serv_options = rhs._serv_options;
            _body_size = rhs._body_size;
            _port = rhs._port;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _server_names = rhs._server_names;
            _locations = rhs._locations;
        }
        Server& operator=(const Server& rhs)
        {
            if (this == &rhs) return *this;
            _serv_options = rhs._serv_options;
            _body_size = rhs._body_size;
            _port = rhs._port;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _server_names = rhs._server_names;
            _locations = rhs._locations;
            return *this;
        }
        ~Server(){};

        /*GETTERS*/
        unsigned int  getServOptions(void) const {return _serv_options;};
        const unsigned int& getPort(void) const {return _port;};
        const unsigned int& getBodySize(void) const {return _body_size;};
        const std::string& getRootDir(void) const {return _root_dir;};
        const std::string& getIndex(void) const {return _index;};

        std::list<Location> getLocations(void) const {return _locations;};
        std::list<std::string> getServerNames(void) const {return _server_names;};

        /*Setters*/
        void    setPort(const unsigned int& port)
        {
            _port = port;
        };
        void    setBodySize(const unsigned int& body)
        {
            _body_size = body;
        };
        void    setRootDir(const std::string& root_dir)
        {
            _root_dir = root_dir;
        };
        void    setIndex(const std::string& index)
        {
            _index = index;
        };
        void    pushNewServerName(const std::string& server_name)
        {
            _server_names.push_back(server_name);
        };
        void    pushNewLocation(const Location& location)
        {
            _locations.push_back(location);
        };
        void    setServOption(const unsigned int& nbit, char actions)
        {
            if (actions == SET)
                bitset(_serv_options, nbit);
            else if (actions == CLEAR)
                bitclear(_serv_options, nbit);
        };

        /*MEMBER FUNCTION*/
        bool    checkBits(const unsigned int& nbit) const
        {
            return (bitcheck(_serv_options, nbit) > 0);
        }
    private:
        unsigned int    _serv_options;
        unsigned int    _port;
        unsigned int    _body_size;
        std::string     _root_dir;
        std::string     _index;
        std::list<std::string> _server_names;
        std::list<Location> _locations;
};



int main (int argc, char **argv)
{
    try
    {
        TcpServer tcp_servers(argc > 1 ? argv[1] : "");
        Server a;
        Server b;
        Server c;
        a.setPort(1500);
        b.setPort(2500);
        c.setPort(3500);
        tcp_servers.pushNewServer(a);
        tcp_servers.pushNewServer(b);
        tcp_servers.pushNewServer(c);
        std::list<Server>::iterator it;
        for (it = tcp_servers.getServers().begin(); it != tcp_servers.getServers().end() ; it++)
        {
            std::cout << &*it << std::endl;
            std::cout << "-----------NEXT_SERV-------------

";
        }
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
    
}
问题原因

核心错误出在TcpServer::getServers()的返回值设计:

std::list<Server> getServers(void) const {return _servers;};

该方法返回的是**_servers的副本**,而非原列表的引用。在遍历循环中:

for (it = tcp_servers.getServers().begin(); it != tcp_servers.getServers().end() ; it++)
  • 第一次调用getServers()生成临时列表副本,it指向这个副本的起始位置
  • 临时副本在语句结束后立即被销毁,it变成悬空迭代器
  • 后续循环中操作it++或访问*it时,实际操作的是已释放的内存,直接触发段错误
  • 同时每次调用getServers()都会生成新副本,it != tcp_servers.getServers().end()比较的是两个不同副本的迭代器,逻辑完全错误
解决方案

修改getServers()的返回值为const引用,避免返回副本:

const std::list<Server>& getServers(void) const {return _servers;};

若需要修改列表内容,可额外提供非const版本的引用返回:

std::list<Server>& getServers(void) {return _servers;};

同时在遍历前获取一次列表引用,避免重复调用生成不必要的副本:

const std::list<Server>& servers = tcp_servers.getServers();
for (std::list<Server>::const_iterator it = servers.begin(); it != servers.end() ; ++it)
{
    std::cout << &*it << std::endl;
    std::cout << "-----------NEXT_SERV-------------\n";
}
修正后的完整代码
#include <string>
#include <iostream>
#include <list>

# define GET 1
# define POST 2
# define DELETE 3
# define SET -1
# define CLEAR -2
# define ALL_METHODS 7

#define bitset(byte,nbit)   (byte |= (1 << nbit))
#define bitclear(byte,nbit) (byte &= ~(1 << nbit))
#define bitcheck(byte,nbit) (byte & (1 << nbit))

class Server;
class Location;
class TcpServer
{
    public:
        TcpServer(const std::string& filename){(void)filename;};
        ~TcpServer(){};

        /*GETTERS*/
        const std::list<Server>& getServers(void) const {return _servers;};
        std::list<Server>& getServers(void) {return _servers;};

        /*SETTERS*/
        void pushNewServer(const Server& server){_servers.push_back(server);};
    private:
        TcpServer(const TcpServer& rhs);
        TcpServer& operator=(const TcpServer& rhs);
        TcpServer();
        std::list<Server> _servers;
};

class Location
{
    public:
        Location()
            :_location_options(0),_body_size(0),_index(""),_root_dir(""),_uri(""),_server(0){};
        Location(const Location& rhs)
        {
            _location_options = rhs._location_options;
            _body_size = rhs._body_size;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _uri = rhs._uri;
            _sub_locations = rhs._sub_locations;
            _server = rhs._server;
        }
        Location& operator=(const Location& rhs)
        {
            if (this == &rhs) return *this;
            _location_options = rhs._location_options;
            _body_size = rhs._body_size;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _uri = rhs._uri;
            _sub_locations = rhs._sub_locations;
            _server = rhs._server;
            return *this;
        }
        ~Location(){};
    
        /*GETTERS*/
        unsigned int&  getLocationsOptions(void) {return _location_options;};
        const unsigned int& getBodySize(void) const {return _body_size;};
        const std::string& getRootDir(void) const {return _root_dir;};
        const std::string& getIndex(void) const {return _index;};
        const std::string& getUri(void) const {return _uri;};
        std::list<Location> getSubLocations(void) const {return _sub_locations;};
        const Server* getServer(void) const {return _server; };

        /*Setters*/
        void    setBodySize(const unsigned int& body)
        {
            _body_size = body;
        };
        void    setIndex(const std::string& index)
        {
            _index = index;
        };
        void    setRootDir(const std::string& root_dir)
        {
            _root_dir = root_dir;
        };
        void    setUri(const std::string& uri)
        {
            _uri = uri;
        };
        void    pushNewLocation(const Location& location)
        {
            _sub_locations.push_back(location);
        };
        void    setServer(Server *server)
        {
            _server = server;
        };

        void    setLocationOption(const unsigned int& nbit, char actions)
        {
            if (actions == SET)
                bitset(_location_options, nbit);
            else if (actions == CLEAR)
                bitclear(_location_options, nbit);
        };

        /*MEMBER FUNCTION*/
        bool    checkBits(const unsigned int& nbit) const
        {
            return (bitcheck(_location_options, nbit) > 0);
        }
    private:
        unsigned int    _location_options;
        unsigned int    _body_size;
        std::string _index;
        std::string _root_dir;
        std::string _uri;
        std::list<Location> _sub_locations;
        Server  *_server;
};

class Server
{
    public:
        Server()
            :_serv_options(0),_port(0),_body_size(0),_root_dir(""),_index(""){};
        Server(const Server& rhs)
        {
            _serv_options = rhs._serv_options;
            _body_size = rhs._body_size;
            _port = rhs._port;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _server_names = rhs._server_names;
            _locations = rhs._locations;
        }
        Server& operator=(const Server& rhs)
        {
            if (this == &rhs) return *this;
            _serv_options = rhs._serv_options;
            _body_size = rhs._body_size;
            _port = rhs._port;
            _root_dir = rhs._root_dir;
            _index = rhs._index;
            _server_names = rhs._server_names;
            _locations = rhs._locations;
            return *this;
        }
        ~Server(){};

        /*GETTERS*/
        unsigned int  getServOptions(void) const {return _serv_options;};
        const unsigned int& getPort(void) const {return _port;};
        const unsigned int& getBodySize(void) const {return _body_size;};
        const std::string& getRootDir(void) const {return _root_dir;};
        const std::string& getIndex(void) const {return _index;};

        std::list<Location> getLocations(void) const {return _locations;};
        std::list<std::string> getServerNames(void) const {return _server_names;};

        /*Setters*/
        void    setPort(const unsigned int& port)
        {
            _port = port;
        };
        void    setBodySize(const unsigned int& body)
        {
            _body_size = body;
        };
        void    setRootDir(const std::string& root_dir)
        {
            _root_dir = root_dir;
        };
        void    setIndex(const std::string& index)
        {
            _index = index;
        };
        void    pushNewServerName(const std::string& server_name)
        {
            _server_names.push_back(server_name);
        };
        void    pushNewLocation(const Location& location)
        {
            _locations.push_back(location);
        };
        void    setServ
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:38:57