首页 > 解决方案 > C++ 编译器的奇怪行为

问题描述

我在这个问题上关心的不是错误在哪里,而是为什么编译器会以这种特殊方式响应这个错误。该错误是在第一个循环中 k==4 的情况下。“current”的值有时可能是-1,这会导致问题。

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

struct com
{
    int type,k,ver;
    string s,res;
    bool b;
    com()
    {
        k=type=ver=-1;
        s="";
        b=false;
        res="";
    }
};
int main() {
    int Q,k;
    string W;
    cin>>Q;
    int current=0;
    vector<com> com_his;
    for(int i=0;i<Q;i++) //<--FIRST LOOP
    {
        cin>>k;
        if(k==1)
        {
            cin>>W;
            com t;
            t.type=1;
            t.s=W;
            // if(com_his)
            t.ver=i;
            current=i;
            com_his.push_back(t);
        }
        else if(k==2)
        {
            cin>>k;
            com t;
            t.type=2;
            t.k=k;
            t.ver=i;
            current=i;
            com_his.push_back(t);
        }
        else if(k==3)
        {
            cin>>k;
            com t;
            t.type=3;
            t.k=k;
            t.ver=current;
            // while()
            com_his[current].b=true;
            com_his.push_back(t);
        }
        else if(k==4)
        {
            // cin>>W;
            com t;
            t.type=4;
            // t.s=W;
            current--;
            while(com_his[current].type==3||com_his[current].type==4)
                  current--;
            t.ver=current;
            com_his[current].b=true;//<--THIS IS THE BUG. SOMETIMES "current" can be -1 which causes the issue.
            com_his.push_back(t);
        }
    }
    string s="";
    cout<<"SIZE IS "<<com_his.size()<<endl;
    for(int i=0;i<Q;i++)  //<--SECOND LOOP
    {
        k=com_his[i].type;
        cout<<i<<" "<<Q<<endl;
        cout<<"HOWDY"<<endl;
    }
    
    // cout<<"HALLO\n";
    return 0;
}

但是我担心的是为什么编译器在发生这种情况时不说分段错误?例如,如果我提供此输入

10
1 lchbfcjtfpsmjrqsdgci
3 19
1 cpcvixlm
1 apdjgjydvpbpvyiy
2 29
4
4
3 9
4
4

我在尝试过的所有不同编译器中都得到了这个输出:

SIZE IS 10
0 10
HOWDY
1 10
HOWDY
2 10
HOWDY
3 10
HOWDY
4 10
HOWDY
5 10
HOWDY
6 10
HOWDY
7 10
HOWDY
8 10
HOWDY
9 10
HOWDY

然后我得到一个错误。在不同的编译器中,我得到不同的错误。使用Hakerrank时出现此错误:

    double free or corruption (!prev)

    Reading symbols from Solution...done.

    [New LWP 73923]

    [Thread debugging using libthread_db enabled]

    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

    Core was generated by `./Solution'.

    Program terminated with signal SIGABRT, Aborted.

    #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50

    To enable execution of this file add

        add-auto-load-safe-path /usr/local/lib64/libstdc++.so.6.0.25-gdb.py

    line to your configuration file "//.gdbinit".

    To completely disable this security protection add

        set auto-load safe-path /

    line to your configuration file "//.gdbinit".

    For more information about this security protection see the

    "Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:

        info "(gdb)Auto-loading safe path"

在 Windows 中使用 Dev C++ 5.11 时,我得到了这个:

Process exited after 8.516 seconds with return value 3221226356

https://www.onlinegdb.com/在在线 gdb 上使用 c++ 14 时,我得到了这个:

Compiled Successfully. memory: 2792 time: 0.17 exit code: 134

我的问题是,如果在第一个循环中访问的内存不足,为什么第二个循环甚至会执行?尽管它们的错误不同,但所有 3 个编译器的输出都是相同的。那么代码是如何到达第二个循环的呢?我只是想了解这种行为。

有关更多信息:我试图解决这个问题: https ://www.hackerrank.com/challenges/simple-text-editor/problem 在这个挑战中,您必须实现一个简单的文本编辑器。最初,您的编辑器包含一个空字符串 S。您必须执行以下类型的 Q 操作:

1)append(W):将字符串W追加到S的末尾。

2)delete(k):删除S的最后k个字符。

3)print(k):打印S的第k个字符。

4)undo:撤消最后一次(之前没有撤消的)类型 1 或 2 的操作,将 S 恢复到该操作之前的状态。

输入格式

第一行包含一个整数 Q,表示操作数。Q 的每一行 i 的后续行(其中 0<=i<Q)定义了要执行的操作。每个操作都以一个整数 t 开头(其中 t={1,2,3,4}),表示上述问题陈述中定义的一种操作类型。如果该操作需要一个参数,则后面是其空格分隔的参数 t。例如,如果 t=1 和 W="abcd" ,第 i 行将是1 abcd

标签: c++

解决方案


com_his[-1]是未定义的行为。需要明确的是:运行时错误,而不是编译错误。

不同的操作系统和不同的编译器可以随心所欲地处理这个问题。


推荐阅读