当我有 iostream 和没有时,结果会有所不同,但没有错误

Results differ when i have iostream and when i don't, but no error

我今天尝试做一些事情,但我的代码出现了一个非常奇怪的行为。当我将#include 留在代码中时,结果与我将其作为注释时的结果不同。也许有人可以看一下并告诉我原因,我将不胜感激。

上述行为适用于某些数据集。这是代码和我的数据集。

26 13
X           X
XXXXXXX  X  X
X        X  X
X  X     X  X
X  X    RX  X
X  XXXXXXX  X
X           X
X XX XXXXX  X
XXXX XX  X  X
X        X  X
X  X     X  X
X  X     X  X
X  XXXXXXX  X
X           X
X X XXXXXX  X
XXX XXX  X  X
X        X  X
X  X     X  X
X  X     X  X
X  XXXXXXX  X
X           X
X X XXX XX  X
X X XX XXXX X
X X XX X    X
X XX        X
J    XXX XXXX

#include <cstdio>
#include <iostream>

#define MAX 101

using namespace std;

struct leeR
{
    int x, y;
}c[MAX*MAX], ir, ij;

int R[MAX][MAX], J[MAX][MAX];
int n, m, dx[] = { 0, 1, 1, 1, 0, -1, -1, -1 }, dy[] = { 1, 1, 0, -1, -1, -1, 0, 1 };

void read()
{
    freopen ( "rj.in", "r", stdin );
    scanf ( "%d%d%c", &n, &m, &R[1][1] );
    char w;
    for ( int i = 1; i <= n; ++i )
        for ( int j = 1; j <= m + 1; ++j )
        {
            scanf ( "%c", &w );
            if ( w == 'R' )
                ir.x = i, ir.y = j;
            else if ( w == 'J' )
                ij.x = i, ij.y = j;
            else if ( w == 'X' )
                R[i][j] = -1;
            J[i][j] = R[i][j];
        }
    fclose(stdin);
}

void dump()
{
    for ( int i = 1; i <= n; ++i )
    {
        for ( int j = 1; j <= m; ++j )
            printf ( "%d ", R[i][j] );
        printf ( "\n\n" );
    }
    printf ( "\n\n" );
    for ( int i = 1; i <= n; ++i )
    {
        for ( int j = 1; j <= m; ++j )
            printf ( "%d ", J[i][j] );
        printf ( "\n\n" );
    }
}

void leeR()
{
    int p(0), f(1);
    c[1] = ir;
    R[ir.x][ir.y] = 1;
    do
    {
        ++p;
        for ( int i = 0; i <= 7; ++i )
            if ( c[p].x + dx[i] > 0 && c[p].y + dy[i] > 0 && !R[c[p].x + dx[i]][c[p].y + dy[i]] )
                R[ c[p].x + dx[i] ][ c[p].y + dy[i] ] = R[c[p].x][c[p].y] + 1,
                c[++f].x = c[p].x + dx[i],
                c[f].y = c[p].y + dy[i];
        if ( p == f )
            break;
    }while ( f != p + 1 );
}

void leeJ()
{
    int p(0), f(1);
    c[1] = ij;
    J[ij.x][ij.y] = 1;
    do
    {
        ++p;
        for ( int i = 0; i <= 7; ++i )
            if ( c[p].x + dx[i] <= n && c[p].y + dy[i] <= m && c[p].x + dx[i] > 0 && c[p].y + dy[i] > 0 && !J[c[p].x + dx[i]][c[p].y + dy[i]] )
                J[ c[p].x + dx[i] ][ c[p].y + dy[i] ] = J[c[p].x][c[p].y] + 1,
                c[++f].x = c[p].x + dx[i],
                c[f].y = c[p].y + dy[i];
        if ( p == f )
            break;
    }while ( f != p + 1 );
}

void check()
{
    freopen ( "rj.out", "w", stdout );
    int X, Y, M(200000);
    for ( int i = 1; i <= n; ++i )
        for ( int j = 1; j <= m; ++j )
            if ( R[i][j] == J[i][j] && R[i][j] < M && R[i][j] > 0 )
                M = R[i][j], X = i, Y = j;
    printf ( "%d %d %d\n", X, Y, M );
    fclose(stdout);
}

int main()
{
    read();
    leeR();
    leeJ();
    check();
    //dump();
    return 0;
}

我建议你试试:

g++ test.cpp -fsanitize=address -g -O0 -std=c++11 这允许您在 "something bad" 发生时收到错误消息。

然后,将程序加载到 GDB 中:

gdb ./a.out break __asan_report_error run backtrace

此时,我在第 62 行(或大约)看到缓冲区溢出:

if ( c[p].x + dx[i] > 0 && c[p].y + dy[i] > 0 && !R[c[p].x + dx[i]][c[p].y + dy[i]] )

此时,你可以做到info locals。对我来说,它打印:

(gdb) info locals i = 3 p = 7937 f = 8119

现在,我不打算为您调试这个,但这应该足以让您找出您的逻辑哪里出了问题。