C++中vector.push_back()触发Segmentation Fault问题求助
Detected_Object to Vector Hey there! Let's break down why you're hitting that segmentation fault when using push_back() with your vector<Detected_Object>—even though vector methods like size() work fine. Segfaults here almost always tie back to memory mismanagement with your custom class or buggy file reading logic. Let's walk through the most likely fixes:
1. Fix Your Detected_Object Class's Copy Behavior
If your class uses raw pointers (like char* for strings) or dynamically allocated memory, the default copy constructor/assignment operator will do a shallow copy. That means when push_back() copies your object into the vector, both the original and the copied object will point to the same chunk of memory. Later, when the vector resizes (or your program cleans up), this leads to double-freeing memory—boom, segfault.
- Easy Fix for Newbies: Replace raw pointers with
std::string(for text) or smart pointers (likestd::unique_ptrfor other dynamic data). These handle deep copying automatically, so you don't have to write custom copy logic. - If You Need Raw Pointers: Explicitly implement a copy constructor and copy assignment operator that duplicates the underlying memory instead of just copying the pointer.
2. Fix Your File Reading Logic
Bad input handling can write garbage values to your Detected_Object members (like uninitialized pointers), which triggers segfaults when you push the object to the vector. Here's what to check:
- Always Verify File Open Success: If your file path is wrong or you don't have read permissions,
ifstreamwill fail silently, and subsequent reads will fill your object with garbage. Add this check right after opening:std::ifstream file("your_file.txt"); if (!file.is_open()) { std::cerr << "Error: Could not open the file!" << std::endl; return 1; } - Avoid Mixed
cinandgetline: If you usecin >>to read values, it leaves the newline character in the input buffer. The nextgetline()will read an empty line, leading to failed word extraction. Instead, read each full line withgetline(), then parse it withstd::istringstream:std::string line; while (std::getline(file, line)) { std::istringstream line_parser(line); std::string w1, w2, w3, w4; // Only create the object if we successfully read 4 words if (line_parser >> w1 >> w2 >> w3 >> w4) { obj_vec.push_back(Detected_Object(w1, w2, w3, w4)); } else { std::cerr << "Skipping invalid line: " << line << std::endl; } }
3. Fix Issues with Pointer-Based Vectors
If you tried using vector<Detected_Object*> and still got segfaults, you're probably making one of these mistakes:
Storing Stack Object Addresses: If you do
Detected_Object temp; vec.push_back(&temp);, thetempobject lives on the stack and gets destroyed after the loop/scope. The vector is left with a dangling pointer, which causes segfaults when accessed.Uninitialized Pointers: If you push a
nullptror an unallocated pointer into the vector, accessing it will crash your program.Fix: Use
newto allocate objects on the heap (and remember todeletethem later), or better yet, usestd::unique_ptrto automate memory management:std::vector<std::unique_ptr<Detected_Object>> obj_vec; // ... inside the read loop ... obj_vec.push_back(std::make_unique<Detected_Object>(w1, w2, w3, w4));
Example Working Code
Here's a complete, safe example to reference:
#include <iostream> #include <fstream> #include <vector> #include <sstream> #include <string> class Detected_Object { public: std::string word1, word2, word3, word4; // Simple constructor to initialize members Detected_Object(std::string w1, std::string w2, std::string w3, std::string w4) : word1(std::move(w1)), word2(std::move(w2)), word3(std::move(w3)), word4(std::move(w4)) {} }; int main() { std::vector<Detected_Object> objects; std::ifstream input_file("data.txt"); if (!input_file.is_open()) { std::cerr << "Failed to open file!" << std::endl; return 1; } std::string line; while (std::getline(input_file, line)) { std::istringstream iss(line); std::string w1, w2, w3, w4; if (iss >> w1 >> w2 >> w3 >> w4) { // emplace_back is more efficient than push_back here objects.emplace_back(w1, w2, w3, w4); } } std::cout << "Total objects in vector: " << objects.size() << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者S.Vishwakarma

