【问题标题】:Getting process exited normally using Gdb debugger使用 Gdb 调试器正常退出进程
【发布时间】:2020-12-21 06:07:20
【问题描述】:

我是 CPP 问题解决的初学者,但遇到了这个问题:- Q)给定一个未排序的非负整数数组,找到一个与给定数相加的连续子数组。 我正在用 gdb 调试它并且没有得到任何输出,它显示进程退出正常情况下是次等的 1。 关于为什么会发生的任何建议?

#include <stdio.h>
#include<iostream>
#include<vector>
using namespace std;
void subarray(vector<int> &a,int s,int n);
int main() {
    int t,n,s,x;
    cin>>t;
    vector<int> v;
    while(t)
    {
        cin>>n>>s;
        for(int i=0;i<n;i++)
        {  
            cin>>x;
            v.push_back(x);
        }
        subarray(v,s,n);
        t--;
        v.clear();
    }
    return 0;
}
void subarray(vector<int> &a,int s,int n)
{
    int j,sum,i=0;
    while(j<n&&i<n)
    {
        sum+=a[j];
        if(sum>s)
        {
            sum=sum-a[i];
            i++;
            j=i;
        }
        if(sum<s)
        {
          j++;  
        }
        else
        {
            cout<<i+1<<" "<<j+1<<endl;
            break;
        }
        if(j==n&&i<n)
        {
          i++;
          j=i;
        }
        if(j==n&&i==n)
        {
            cout<<-1<<endl;
            break;
        }
       
    }
    

}

【问题讨论】:

  • 调试器找不到错误。它们可以帮助您找到错误。您要做的是使用调试器逐行执行程序,并查看程序的行为与您预期的偏差在哪里。意外几乎总是一个错误。
  • 我猜这是因为您的子数组方法中有这一行 int j,sum,i=0; 这意味着 int j; int sum; int i=0;。在您尝试从具有错误索引sum+=a[j]; 的向量中获取值之后。我认为这不是你想要的。如果您想在一行中初始化多个变量,请像 int a = 0, b = 0, c = 0, d = 0;int a = 0, b = a, c = a, d = a; 这样操作。
  • int j,sum,i=0; where j in uninitialized 在第一次调用while(j&lt;n&amp;&amp;i&lt;n)sum+=a[j]; 等时。请充分留出您的代码。理解while(j&lt;n&amp;&amp;i&lt;n)while (j &lt; n &amp;&amp; i &lt; n) 更难读懂老眼睛。 (谢谢你的教授和老板)另外,继续前进,考虑Why is “using namespace std;” considered bad practice?

标签: c++ arrays debugging


【解决方案1】:

您的直接问题在于subarray(),其中jsumint j,sum,i=0; 之后未初始化,因此在您的第一次循环迭代中,您调用未定义的行为当您尝试访问每个变量的值不确定时。其中包括:

    int j,sum,i=0;
    while(j<n&&i<n)
    {
        sum+=a[j];    /* likely SegFaults when index is wildly outside vector bounds */

在 gdb 中,您的代码在 gdb 自己的受保护内存空间中执行,因此您可以避免那里的段错误,而在 gdb 之外运行时可能会出现段错误。

如果您只是使用Warnings Enabled进行编译,所有这些问题都会被发现。始终在启用警告的情况下进行编译,并且不要接受代码,直到它在没有警告的情况下编译。要启用警告,请将 -Wall -Wextra -pedantic 添加到您的 gcc/clang 编译字符串(也可以考虑添加 -Wshadow 以警告阴影变量)。对于 VS(Windows 上为cl.exe),请使用/W3。所有其他编译器将具有类似的选项。阅读并理解每个警告——然后去修复它。他们将识别任何问题,以及它们发生的确切位置。

不要让您的用户盯着屏幕上闪烁的光标想知道您的程序是否挂起。提示用户输入,以便他们对预期的内容有所了解。然后验证每个用户输入并确保提供的值在任何需要的范围内。解决直接问题以避免未定义的行为,验证所有用户输入,并提供以下 cmets 的其他建议,您将拥有:

// #include <stdio.h>   /* do not include unnecessary headers */
#include <iostream>
#include <vector>

void subarray (std::vector<int> &a,int s,int n);

int main (void) {
    
    int t;
    
    std::cout << "enter value for t: ";     /* prompt */
    if (!(std::cin>>t)) {   /* validate EVERY user-input */
        std::cerr << "error: invalid integer input 't'.\n";
        return 1;
    }
    if (t < 1) {    /* valid EVERY value is within a valid range (if applicable) */
        std::cerr << "error: integer must be greater than 1.\n";
        return 1;
    }
    
    std::vector<int> v{};   /* brace initialize object as empty */
    
    while (t)               /* loop t times */
    {
        int n, s;           /* declare variables in the scope needed */
        
        std::cout << "\nenter values for n & s: ";
        if (!(std::cin >> n >> s)) {    /* validate EVERY user-input */
            std::cerr << "error: invalid integer input 'n', 's'.\n";
            return 1;
        }
        if (n < 1) {    /* valid EVERY value is within a valid range (if applicable) */
            std::cerr << "error: integer must be greater than 1.\n";
            return 1;
        }
        /* same for s */
        
        for (int i = 0; i < n; i++)
        {  
            int x;                  /* declare in scope */
            
            std::cout << "  v[" << i << "]: ";
            if (std::cin >> x)      /* validate */
                v.push_back(x);     /* add to vector */
        }
        subarray (v, s, n);
        
        t--;
        v.clear();
    }
}

void subarray (std::vector<int> &a, int s, int n)
{
    int j = 0, sum = 0, i = 0;      /* initialize all values */
    while (j < n && i < n) {
        sum += a[j];
        
        if (sum > s) {
            sum = sum - a[i];
            i++;
            j = i;
        }
        else if (sum < s) {
            j++;  
        }
        else {
            std::cout << i+1 << " " << j+1 << '\n';
            break;
        }
        
        if (j == n) {
            if (i < n) {
                i++;
                j = i;
            }
            if (i == n) {
                std::cout << -1 << '\n';
            }
        }
    }
}

您的代码现在将在没有警告的情况下编译 -- 但您必须确认代码的逻辑。这是留给你的。

使用/输出示例

添加提示后,您的程序会提供以下输出:

$ ./bin/subarraychk
enter value for t: 3

enter values for n & s: 3 4
  v[0]: 8
  v[1]: 2
  v[2]: 6
-1

enter values for n & s: 4 1
  v[0]: 0
  v[1]: 2
  v[2]: 3
  v[3]: 4
-1

enter values for n & s: 5 3
  v[0]: 2
  v[1]: 4
  v[2]: 6
  v[3]: 8
  v[4]: 10
-1

正如上面评论中提到的,using namespace std; 已被删除。见Why is “using namespace std;” considered bad practice?endl 的使用被简单的'\n' 取代,见:C++: “std::endl” vs “\n” 代码间距也得到了改进,使代码更具可读性(这也可以帮助您发现任何逻辑或语法错误)

如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 2016-10-30
    相关资源
    最近更新 更多