0

我在这里发帖是因为我在 Google 上找不到任何帮助。

我在 uni 使用 Debian 挤压来编写一些 C 并且可以 ftp 内容以在家工作。但是,我遇到了这个问题:我编译的一个小程序没有任何警告,并且在 uni 上完美运行。但在我的电脑(GNU/Linux 也是如此)上,它根本不存在:以下是条件:-使用“gcc -g -o -Wextra -ansi prog prog.c”-在 uni 工作,此处为 segfault -valgrind给了我这个:

==4305== Invalid read of size 1
==4305==    at 0x4EBCD60: __GI___rawmemchr (in /usr/lib/libc-2.18.so)
==4305==    by 0x4EA9581: _IO_str_init_static_internal (in /usr/lib/libc-2.18.so)
==4305==    by 0x4E99DB6: __isoc99_vsscanf (in /usr/lib/libc-2.18.so)
==4305==    by 0x4E99D56: __isoc99_sscanf (in /usr/lib/libc-2.18.so)
==4305==    by 0x400B69: main (chomp.c:108)
==4305==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4305== 
==4305== 
==4305== Process terminating with default action of signal 11 (SIGSEGV)
==4305==  Access not within mapped region at address 0x0
==4305==    at 0x4EBCD60: __GI___rawmemchr (in /usr/lib/libc-2.18.so)
==4305==    by 0x4EA9581: _IO_str_init_static_internal (in /usr/lib/libc-2.18.so)
==4305==    by 0x4E99DB6: __isoc99_vsscanf (in /usr/lib/libc-2.18.so)
==4305==    by 0x4E99D56: __isoc99_sscanf (in /usr/lib/libc-2.18.so)
==4305==    by 0x400B69: main (chomp.c:108)
==4305==  If you believe this happened as a result of a stack
==4305==  overflow in your program's main thread (unlikely but
==4305==  possible), you can try to increase the size of the
==4305==  main thread stack using the --main-stacksize= flag.
==4305==  The main thread stack size used in this run was 8388608.

这是程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
    int** tab;
    int n;
    int m;
    }Tablette;

typedef enum{J1,J2}Joueur;

typedef struct{
    Tablette T;
    Joueur J;
    }Position;

typedef struct{
    int x;
    int y;
    }Coup;

Tablette creer_tablette(int n, int m){
    Tablette T;
    int i,j;
    T.n=n;
    T.m=m;
    T.tab = (int**) malloc(n * sizeof(int*));
    if(T.tab==NULL){
        printf("Erreur\n");
        exit(1);
    }
    for(i=0;i<n;i++){
        T.tab[i]=(int*)malloc(sizeof(int)*m);
    }
    for(i=0;i<n;i++){
        if(T.tab[i]==NULL){
            printf("Erreur\n");
            exit(1);
    }
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            T.tab[i][j]=1;
        }
    }
        }
return T;
}

void afficher_tablette(Tablette T){
    int i,j;
    printf("  ");
    for(j=0;j<T.m;j++)
        printf("%d ",j+1);
    printf("\n");
    for(i=0;i<T.n;i++){
        printf("%d ",i+1);
        for(j=0;j<T.m;j++){
            if(T.tab[i][j]==1)
                printf("■ ");
            }
        printf("\n");
    }
    printf("\n");
}

void manger_tablette(Tablette *T, int x, int y){
    int i,j;
    for(i=x;i<T->n;i++){
        for(j=y;j<T->m;j++){
            T->tab[i][j]=0;
        }
    }
}

int est_legal(Position *pos, Coup *cp){
    if((cp->x)<0 || (cp->x)>(pos->T.m) || (cp->y)<0 || (cp->y)>(pos->T.n))
        return 0;
    if(pos->T.tab[cp->y][cp->x]==0)
        return 0;
    return 1;
}

int fin_jeu(Position *pos, Joueur *win){
    if(pos->T.tab[0][0]==0){
        *win=pos->J;
        return 1;
    }
    return 0;
}

void jouer_coup(Position *pos, Coup *cp){
    if(est_legal(pos,cp)==1)
        manger_tablette(&(pos->T),(cp->y-1),(cp->x-1));
    pos->J=(pos->J+1)%2;
}

int main(int argc, char *argv[]){
    int n,m;
    sscanf(argv[2],"%d",&m);
    sscanf(argv[1],"%d",&n);
    Tablette T=creer_tablette(n,m);
    Coup cp;
    Position pos;
    Joueur win;
    pos.T=T;
    pos.J=J1;
    while(fin_jeu(&pos,&win)!=1){
        afficher_tablette(T);
        printf("Au tour du Joueur %d\n",pos.J+1);
        printf("Entrez les coordonnées du carré que vous souhaitez manger\n");
        scanf("%d",&(cp.x));
        scanf("%d",&(cp.y));
            while(est_legal(&pos,&cp)==0){
                printf("Coordonnées non valides\n");
                scanf("%d",&(cp.x));
                scanf("%d",&(cp.y));
            }
        jouer_coup(&pos,&cp);
    }
    printf("Le Joueur %d a gagné !\n",pos.J+1);
    return 0;
}

感谢您的关注。

4

2 回答 2

3
for(i=0;i<n;i++){
    if(T.tab[i]==NULL){
        printf("Erreur\n");
        exit(1);
}
for(i=0;i<n;i++){
    for(j=0;j<m;j++){
        T.tab[i][j]=1;
    }
}
    }

You have a { and } bug. The second for loop is inside the first for loop and both modifies i.

于 2013-10-16T18:53:53.840 回答
1

T.tab 的大小为m*n. 因此该检查无效。

if((cp->x)<0 || (cp->x)>(pos->T.m) || (cp->y)<0 || (cp->y)>(pos->T.n))

将其更改为

if((cp->x)<0 || (cp->x)>=(pos->T.m) || (cp->y)<0 || (cp->y)>(pos->=T.n))
于 2013-10-16T18:57:02.503 回答