Tôi có một chức năng,Trình quản lý mô-đun::tick()
, mã như sau:
void Trình quản lý mô-đun::tick()
{
tự động ngay bây giờ = std::chrono::steady_clock::now();
auto nowSys = std::chrono::system_clock::now().time_since_epoch();
for(auto& m : m_modules)
{
if(std::chrono::duration_cast(now - m.second) >=
std::chrono::seconds(m.first.m_settings.m_interval))
{
std::string result = m.first.run(); //run() trả về chuỗi std::
m.giây = bây giờ;
thử
{
Kết nối HTTPConn("127.0.0.1", 80);
conn.request("POST", "/", std::vector{"Host: localhost", "Connection: close"}, result);
}
bắt(HTTPException& e)
{
Log::write(e.getErrorString());
}
}
}
Chương trình bắt đầu từ HTTPConn::request()
Segfault xảy ra khi trả về hàm, trong hàm hủy basic_string (đã sử dụng GDB để xác định điều này). Nếu tôi nhận xét tất cả mã trong hàm request() thì lỗi segfault vẫn xảy ra, do đó vấn đề phải nằm ngoài hàm đó.
Tôi nghĩ vấn đề là ở chỗ tôi HTTPConn
Ở đâu đó trong hàm tạo, tôi đã làm hỏng vùng heap. Mã này như sau:
HTTPConn::HTTPConn(const std::string& Host, int port)
{
gợi ý addrinfo;
addrinfo* res;
memset(&hints, 0, sizeof(hints));
gợi ý.ai_family = AF_UNSPEC;
gợi ý.ai_socktype = SOCK_STREAM;
int result = getaddrinfo(host.c_str(), std::to_string(port).c_str(), &hints, &res);
nếu (kết quả)
{
ném HTTPException (HTTPE_GETADDRINFO_FAILED);
}
addrinfo* ptr = res;
bool validSocket = false;
trong khi(ptr)
{
m_socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if(m_socket == -1)
{
ptr = ptr->ai_next;
}
khác
{
validSocket = true;
phá vỡ;
}
}
if(!validSocket)
{
freeaddrinfo(res);
ném HTTPException (HTTPE_SOCKET_FAILED);
}
result = connect(m_socket, ptr->ai_addr, ptr->ai_addrlen);
freeaddrinfo(res);
nếu (kết quả == -1)
{
đóng(m_socket);
m_socket = -1;
if(errno == ECONREFUSED)
{
ném HTTPException (HTTPE_CONNECTION_REFUSED);
}
khác nếu(errno == ENETUNREACH)
{
ném HTTPException (HTTPE_NETWORK_UNREACHABLE);
}
khác nếu(errno == ETIMEDOUT)
{
ném HTTPException(HTTPE_TIMED_OUT);
}
khác
{
ném HTTPException (HTTPE_CONNECT_FAILED);
}
}
}
Tôi xin lỗi vì số lượng mã lớn; tôi đã cố gắng tạo một ví dụ ngắn gọn, khép kín nhưng không thể tái tạo lại vấn đề.
gia hạn
Vì vậy, vấn đề có vẻ là tôi không trả lại bất kỳ thứ gì trong hàm HTTPConn::request std::chuỗi
đối tượng, nhưng nó được tuyên bố là có std::chuỗi
Kiểu trả về. Câu hỏi của tôi bây giờ là: tại sao lại biên dịch? Đây là dòng lệnh tôi đã sử dụng để biên dịch nó, sử dụng g++ 4.8.2:
g++ -Iinclude -std=c++11 -g -D__DEBUG -c src/HTTP.cpp -o obj/HTTP.o
Không có cảnh báo hoặc lỗi nào được đưa ra.
Vấn đề là tôi đã khai báo HTTPConn::request()
hàm, kiểu trả về là std::chuỗi
, nhưng không có gì được trả lại. Như Frédéric Hamidi đã nói, điều này dẫn đến hành vi không xác định.
Theo tôi, đây phải là cảnh báo được bật theo mặc định trong g++ vì nó có thể dẫn đến hành vi không xác định. Hoặc nó phải là một lỗi. Sẽ -Tường
Cờ được thêm vào lệnh biên dịch sẽ kích hoạt cảnh báo này (hoặc -Wreturn-loại
để chỉ kích hoạt cảnh báo cụ thể đó)
Tôi là một lập trình viên xuất sắc, rất giỏi!