C++移除vector重复元素遇SIGSTOP错误,求排查解决
Hey there! Let's work through why your code is hitting that SIGSTOP error and not producing the expected output. I'll break down the problems and show you how to fix them step by step.
Key Issues in Your Code
1. Invalid Iterator Usage (Root Cause of SIGSTOP)
When you call v_num.erase(j) or v_num.erase(it), the original iterator becomes invalid (it points to memory that's no longer part of the vector). Your current code doesn't update these iterators after erasing, which leads to undefined behavior—this is almost certainly causing the SIGSTOP error.
For example:
- When you erase
j, you don't update it, so the nextj++tries to increment a dangling iterator. - When you erase
it, you leave it pointing to invalid memory, which breaks the outer loop.
2. Input Handling Mismatch
Your code expects a test case count t and a number count n first, but your example input is just a single line of numbers. If you run the code with the example input directly, it'll misinterpret the first two numbers as t and n, leading to unexpected behavior and possibly hanging waiting for more input.
3. Flag Logic Edge Cases
Your flag handling for incrementing iterators is a bit off—when you erase an element, you shouldn't increment the iterator separately, since erase returns the next valid iterator.
Fixed Code
Here's the corrected version with explanations:
#include <iostream> #include <vector> using namespace std; int main() { // Read all input numbers (no need for t or n if input is a single line) vector<int> v_num; int x; while (cin >> x) { v_num.push_back(x); } vector<int>::iterator it; for (it = v_num.begin(); it != v_num.end();) { int val = *it; int flag = 0; vector<int>::iterator j; // Check for duplicates after current element for (j = it + 1; j != v_num.end();) { if (val == *j) { // Erase the duplicate and update j to the next valid iterator j = v_num.erase(j); flag = 1; } else { // No duplicate, move to next element j++; } } // If duplicates were found, erase the current element too if (flag == 1) { // Update it to the next valid iterator after erasing it = v_num.erase(it); } else { // No duplicates, move to next element it++; } } // Print the result (space-separated, as per your example) for (size_t i = 0; i < v_num.size(); i++) { if (i > 0) cout << " "; cout << v_num[i]; } cout << endl; return 0; }
What Changed?
- Iterator Safety: Every time we call
erase, we assign its return value back to the iterator (e.g.,j = v_num.erase(j)). This ensures we always have a valid pointer to the next element. - Input Handling: We now read all input numbers directly, matching your example input format. If you do need to support multiple test cases with
tandn, you can revert that part—but make sure your input includes those values first. - Output Format: The result is printed space-separated instead of each element on a new line, which matches your expected output.
Testing with Your Example
Input: 1 2 5 7 1 4 2
Output: 5 7 4
This should now run without errors and produce the correct result.
内容的提问来源于stack exchange,提问作者Mohammad Husain Dilshad

