C++在读取字符串并存储在向量上时崩溃


#include <iostream>
#include <vector>
using namespace std;
typedef vector<string> VS;
void back(VS &paraules, VS &sol, int n, int i) {
if(i == n) {
cout << "{" << sol[0];
for(int j = 1; j < n; j++) {
cout << "," << sol[i];
}
cout << "}" << endl;
}
else {
for(int j = 0; j < n; j++) {
sol[i] = paraules[j];
back(paraules, sol, n, i+1);
}
}
}
int main() {
int n;
cin >> n;
VS sol(n);
VS paraules(n);
for(int i = 0; i < n; i++) {
cin >> paraules[i];
}
cout << "This won t print";
back(paraules, sol, n, 0); 
}

现在粘贴了整个代码。采用n单词的回溯,只打印单词的所有排列。

我最初认为这是一个阅读问题,因为this wont print没有打印。经过一些测试,我发现在最后一行注释函数调用会使错误消失,代码也不会崩溃。

所以这可能是函数?这仍然不能解释为什么它不打印,因为调用发生在cout之后。

例如,输入可能是:

2再见

由于if语句,您的back函数for循环似乎越界了,请尝试使用n-1而不是

if(i == n-1) 

问题是,对于i == n为true的情况,您有以下语句:

cout << "," << sol[i]; //this leads to undefined behavior

在上面显示的语句中,向量sol的大小是n。但请注意,在这种情况下,由于i等于n,因此通过写入sol[i],您将越界,这将导致未定义的行为。

这是因为索引从0开始,而不是从1开始。

例如,假设向量sol的大小为4。那就是n = 4

现在你基本上要做的是:

cout << "," << sol[4];

但您只能安全地使用索引3以下的元素,即使用sol[0]sol[1]sol[2]sol[3]是安全的。另一方面,使用sol[4]会导致未定义的行为

未定义的行为意味着任何1都可能发生,包括但不限于提供预期输出的程序。但是永远不要依赖(或根据未定义行为的程序的输出得出结论(。

例如,这里的程序似乎不会崩溃,但这里确实会崩溃。


1对于未定义行为的更准确的技术定义,请参阅此处,其中提到:对程序的行为没有限制

我认为代码本身没有问题。你会遇到分段故障,但可能是其他原因造成的。

然而,我假设你的代码看起来是这样的:

#include <vector>
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
vector<string> v(n);
for(int i = 0; i < n; i++) {
cin >> v[i];
}
}

因为您的代码缺少一个结束括号和一个#include <iostream>。您介意复制并粘贴整个代码,还是链接一个存储库?