英文:
Segfault while iterating through std::list<USER_DEFINE_CLASS> with iterator
问题
你遇到的问题似乎是在尝试使用迭代器遍历std::list<User_Defined_Class>
时,当尝试访问第二个迭代器时出现了segmentation fault
错误。这个问题可能与你的迭代器操作有关。
你的代码中,你创建了一个TcpServer
对象,然后实例化了三个Server
对象,并将它们添加到了_servers
成员变量中的std::list<Server>
中。然后,你使用迭代器遍历这个列表,并打印每个Server
对象的内容。
然而,问题可能出现在你遍历列表时,如果_servers
列表中没有足够的元素,尝试访问第二个迭代器可能导致segmentation fault
。请确保你的列表中至少有两个元素,并检查迭代器的使用是否正确。
此外,请确保你的类的成员函数和构造函数/析构函数实现是正确的,以免导致其他潜在问题。
英文:
I am facing a problem in my program where when I try to iterate through my std::list<User_Defined_Class>
with iterator, I get a segmentation fault
when I try to access the second iterator.
Here is the full program, first I instantiate 3 servers and set to them random port number for debugging purpose, then I push them into std::list<Server>
private member of tcp_servers
with the help of the public method pushNewServer
who is implemented like so:
void TcpServer::pushNewServer(const Server& server)
{
_servers.push_back(server);
};
and finally I create an Iterator of the same as my list and iterate until I face the end of my list however when I launch this program I get a segfault.
#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-------------\n\n";
}
}
catch(const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
答案1
得分: 3
以下是您要翻译的代码部分:
问题出在 TcpServer::getServers
函数上:
std::list<Server> getServers(void) const {return _servers;};
因为它返回列表 按值,所以循环
for (it = tcp_servers.getServers().begin(); it != tcp_servers.getServers().end() ; it++)
将有两个不同的列表,它将迭代器与之进行比较。
从 tcp_servers.getServers().begin()
获取的迭代器将针对完全不同的列表,而从 tcp_servers.getServers().end()
获取的迭代器也将如此。
要能够比较迭代器,它们必须都来自完全相同的容器。
简单的解决方案是改为通过引用返回列表:
std::list<Server>& getServers(void) const {return _servers;};
另外,关于默认容器,真的应该使用 std::vector
。除非您有非常特定的要求(我在这里没有看到任何要求),不需要使用 std::list
。
此外,请不要使用显式迭代器 for
循环,除非您对此有非常具体的要求。范围 for
循环 同样有效:
for (auto& server : tcp_servers.getServers())
{
std::cout << &server << '\n';
}
英文:
The problem is with the TcpServer::getServers
function:
std::list<Server> getServers(void) const {return _servers;};
Because it returns the list by value, the loop
for (it = tcp_servers.getServers().begin(); it != tcp_servers.getServers().end() ; it++)
will have two different lists that it compares the iterators with.
The iterator you get from tcp_servers.getServers().begin()
will be for a totally different list than the iterator you get from tcp_servers.getServers().end()
.
To be able to compare iterators they must both come from the exact same container.
The simple solution is to return the list by reference instead:
std::list<Server>& getServers(void) const {return _servers;};
On a different note, the default container should really be std::vector
. Unless you have very specific requirements (and I don't see any here) there no need for std::list
.
Also please don't use explicit iterator for
loops unless you have very specific requirements for it. A range for
loop would work just as well:
for (auto& server : tcp_servers.getServers())
{
std::cout << &server << '\n';
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论