【问题标题】:C++ crashing when reading strings and storing on a vector读取字符串并存储在向量上时 C++ 崩溃
【发布时间】:2021-12-30 20:18:51
【问题描述】:
#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 再见

【问题讨论】:

  • 也许它确实到达func,输入func 并在程序可以发出您期望的任何输出之前在func 内的某个地方崩溃,或者可能在输出发出之后但在终端绘制之前它在屏幕上..
  • minimal reproducible example (MRE) 的真正美妙之处在于,如果不隔离错误并减少其周围的噪音以使问题变得明显,就很难制作出好的 MRE。发现的错误通常是死错误,因此不再需要提问。尽早完成 MRE,您通常会提前完成。如果不是您有误解,我们往往会很快解决这些问题,或者问题是一个需要领域专家的棘手问题。
  • this still doesn t explain why it s not printing, since the call happens after the cout 你传递给cout 的内容是缓冲的,因此如果应用程序在缓冲区刷新之前崩溃,则不会显示任何内容。控制台输出肯定有助于调试,但您应该始终将其与调试器结合使用,以便查看代码的哪些部分实际执行。
  • 对于输入“2 hi bye”,这个:for(int j = 1; j &lt; n; j++) { cout &lt;&lt; "," &lt;&lt; sol[i]; -- 越界。将[] 更改为at(),您将看到问题。 for(int j = 1; j &lt; n; j++) {cout &lt;&lt; "," &lt;&lt; sol.at(i);。当您使用at() 时,如果超出向量范围,将引发std::out_of_range 异常。

标签: c++ segmentation-fault


【解决方案1】:

由于 if 语句,您的后退函数 for 循环似乎超出了界限,请尝试使用 n-1 代替

    if(i == n-1) 

【讨论】:

    【解决方案2】:

    问题是当i == n 为真的情况下,你有这样的陈述:

    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都可能发生包括但不限于给出您预期输出的程序。但是永远不要依赖(或根据)具有未定义行为的程序的输出。

    例如here 程序似乎没有崩溃,但here 它确实崩溃了。


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

    【讨论】:

      【解决方案3】:

      我认为代码本身没有问题。您遇到了段错误,但可能是其他原因造成的。

      但是,我假设您的代码如下所示:

      #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 &lt;iostream&gt;。您介意复制和粘贴整个代码,还是链接存储库?

      【讨论】:

      • 我现在添加了整个代码,这不是括号或包含问题,那只是我粘贴时的错误
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      相关资源
      最近更新 更多