Ошибки при динамическом размещении массивов.vfscanf.c: 1898 - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь создать программу, которая говорит, является ли массив магическим квадратом.Это хорошо работало при создании до 3х3 размеров.Но с 4х4 они ведут себя плохо.5x5 или выше, я получаю ошибку «Ошибка сегментации (записанное изображение ядра)», всегда в одной и той же точке: mat [4] [0].Вот мой код:

#include <stdio.h>
#include <stdlib.h>

int qm(int ** mat, int n){
    int sl = 0, sc = 0, sdP = 0, sdS = 0;
    int i, j;

    for(i = 0; i < n; i++){
        sl += mat[0][i];
        sc += mat[i][0];
        sdP += mat[i][i];
        sdS += mat[i][n-i-1];
    }


    if((sl != sc)||(sl != sdP) || (sl!= sdS)) return 0;
    else{
        for(i = 1; i < n; i++){
            int tempL = 0, tempC = 0;
            for(j = 1; j <= n; j++){
                tempC += mat[j - 1][i];
                tempL += mat[i][j - 1];
            }
            if((tempL != tempC) || (tempL != sl)) return 0;
        }
        return 1;
    }
}

int main(void){
    int ** mat, n, i, j;

    printf("\nINFORME O NUMERO N DE LINHAS E COLUNAS: ");
    scanf("%d", &n);

    mat = (int **) malloc(n * sizeof(int));
    for(i = 0; i < n; i++) {
        mat[i] = (int *) malloc(n * sizeof(int));
    }

    for(i = 0; i < n; i++){
        for(j = 0; j < n; j++){
            printf("\nINFORME MAT[%d][%d]: ", i, j);
            scanf("%d", &mat[i][j]);
        }
    }

    int test = qm(mat, n);

    for(i = 0; i < n; i++){
        free(mat[i]);
    }
    free(mat);


    if(test) printf("\nA MATRIZ É QUADRADO MÁGICO!\n");
    else{
        printf("\nA MATRIZ NÃO É QUADRADO MÁGICO!\n");
    }

    return 0;
}

А вот несколько тестов на GDB:

3x3 матрица:

(gdb) run
Starting program: /home/.../

INFORME O NUMERO N DE LINHAS E COLUNAS: 3

INFORME MAT[0][0]: 1

INFORME MAT[0][1]: 1

INFORME MAT[0][2]: 1

INFORME MAT[1][0]: 1

INFORME MAT[1][1]: 1

INFORME MAT[1][2]: 1

INFORME MAT[2][0]: 1

INFORME MAT[2][1]: 1

INFORME MAT[2][2]: 1

A MATRIZ É QUADRADO MÁGICO!
[Inferior 1 (process 4804) exited normally]

4x4 матрица:

(gdb) run
Starting program: /home/.../

INFORME O NUMERO N DE LINHAS E COLUNAS: 4

INFORME MAT[0][0]: 1

INFORME MAT[0][1]: 1

INFORME MAT[0][2]: 1

INFORME MAT[0][3]: 1

INFORME MAT[1][0]: 1

INFORME MAT[1][1]: 1

INFORME MAT[1][2]: 1

INFORME MAT[1][3]: 1

INFORME MAT[2][0]: 1

INFORME MAT[2][1]: 1

INFORME MAT[2][2]: 1

INFORME MAT[2][3]: 1

INFORME MAT[3][0]: 1

INFORME MAT[3][1]: 1

INFORME MAT[3][2]: 1

INFORME MAT[3][3]: 1
double free or corruption (out)

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c:Arquivo ou diretório inexistente.

5x5:

(gdb) run
Starting program: /home/.../

INFORME O NUMERO N DE LINHAS E COLUNAS: 5

INFORME MAT[0][0]: 1

INFORME MAT[0][1]: 1

INFORME MAT[0][2]: 1

INFORME MAT[0][3]: 1

INFORME MAT[0][4]: 1

INFORME MAT[1][0]: 1

INFORME MAT[1][1]: 1

INFORME MAT[1][2]: 1

INFORME MAT[1][3]: 1

INFORME MAT[1][4]: 1

INFORME MAT[2][0]: 1

INFORME MAT[2][1]: 1

INFORME MAT[2][2]: 1

INFORME MAT[2][3]: 1 

INFORME MAT[2][4]: 1

INFORME MAT[3][0]: 1

INFORME MAT[3][1]: 1

INFORME MAT[3][2]: 1

INFORME MAT[3][3]: 1

INFORME MAT[3][4]: 1

INFORME MAT[4][0]: 1

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a538c2 in _IO_vfscanf_internal (s=<optimized out>, format <optimized out>, argptr=argptr@entry=0x7fffffffdc80, errp=errp@entry=0x0) at vfscanf.c:1898
1898    vfscanf.c: Arquivo ou diretório inexistente.

и 6x6:

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/lucas/Documentos/UFF/ProgEstruturada/EXERCICIOS/labs/test 

INFORME O NUMERO N DE LINHAS E COLUNAS: 6

INFORME MAT[0][0]: 1

INFORME MAT[0][1]: 1

INFORME MAT[0][2]: 1

INFORME MAT[0][3]: 1

INFORME MAT[0][4]: 1

INFORME MAT[0][5]: 1

INFORME MAT[1][0]: 1

INFORME MAT[1][1]: 1

INFORME MAT[1][2]: 1

INFORME MAT[1][3]: 1

INFORME MAT[1][4]: 1

INFORME MAT[1][5]: 1

INFORME MAT[2][0]: 1

INFORME MAT[2][1]: 1

INFORME MAT[2][2]: 1

INFORME MAT[2][3]: 1

INFORME MAT[2][4]: 1

INFORME MAT[2][5]: 1

INFORME MAT[3][0]: 1

INFORME MAT[3][1]: 1

INFORME MAT[3][2]: 1

INFORME MAT[3][3]: 1

INFORME MAT[3][4]: 1

INFORME MAT[3][5]: 1

INFORME MAT[4][0]: 1

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a538c2 in _IO_vfscanf_internal (s=<optimized out>, format=<optimized out>, argptr=argptr@entry=0x7fffffffdc80, errp=errp@entry=0x0) at vfscanf.c:1898
1898    vfscanf.c: Arquivo ou diretório inexistente.

, а затем я попробовал это на GDB:

(gdb) bt
#0  0x00007ffff7a538c2 in _IO_vfscanf_internal (s=<optimized out>, format=<optimized out>, argptr=argptr@entry=0x7fffffffdc80, errp=errp@entry=0x0) at vfscanf.c:1898
#1  0x00007ffff7a5ffd8 in __isoc99_scanf (format=<optimized out>) at isoc99_scanf.c:37
#2  0x0000555555554a97 in main () at labII_exIV.c:44
(gdb) frame 0
#0  0x00007ffff7a538c2 in _IO_vfscanf_internal (s=<optimized out>, format=<optimized out>, argptr=argptr@entry=0x7fffffffdc80, errp=errp@entry=0x0) at vfscanf.c:1898
1898    in vfscanf.c
(gdb) list
1893    in vfscanf.c
(gdb) frame 1
#1  0x00007ffff7a5ffd8 in __isoc99_scanf (format=<optimized out>) at isoc99_scanf.c:37
37  isoc99_scanf.c: Arquivo ou diretório inexistente.
(gdb) list
32  in isoc99_scanf.c
(gdb) frame 2
#2  0x0000555555554a97 in main () at labII_exIV.c:44
warning: Source file is more recent than executable.
44              scanf("%d", &mat[i][j]);
(gdb) list
39      }
40  
41      for(i = 0; i < n; i++){
42          for(j = 0; j < n; j++){
43              printf("\nINFORME MAT[%d][%d]: ", i, j);
44              scanf("%d", &mat[i][j]);
45          }
46      }
47  
48      int test = qm(mat, n);

Я использовал эти команды на основе поискаЯ сделал об ошибке, я нашел на этом сайте: «https://vinipsmaker.wordpress.com/2013/12/20/mug-favorito-de-cc-false-of-segmentacao/". Я увидел предупреждение, что ошибка в строке 44, при вызове scanf (), но я не совсем понял проблему.

Я скомпилировал с gcc в Ubuntu 18.04

1 Ответ

0 голосов
/ 20 сентября 2018

Проблема с этой строкой:

mat = (int **) malloc(n * sizeof(int));

Поскольку mat является указателем на указатель на int, он содержит указатели на int.Таким образом, операция malloc должна иметь указатель sizeof на int.Измените приведенное выше значение на:

mat = (int **) malloc(n * sizeof(int*));

После этого изменения я проверил это для матриц 4x4, 5x5 и 6x6, и оно работает.

Ниже приведен вывод для матрицы 6X6.

INFORME O NUMERO N DE LINHAS E COLUNAS: 6

INFORME MAT[0][0]: 1

INFORME MAT[0][1]: 1

INFORME MAT[0][2]: 1

INFORME MAT[0][3]: 1

INFORME MAT[0][4]: 1

INFORME MAT[0][5]: 1

INFORME MAT[1][0]: 1

INFORME MAT[1][1]: 1

INFORME MAT[1][2]: 1

INFORME MAT[1][3]: 1

INFORME MAT[1][4]: 1

INFORME MAT[1][5]: 1

INFORME MAT[2][0]: 1

INFORME MAT[2][1]: 1

INFORME MAT[2][2]: 1

INFORME MAT[2][3]: 1

INFORME MAT[2][4]: 1

INFORME MAT[2][5]: 1

INFORME MAT[3][0]: 1

INFORME MAT[3][1]: 1

INFORME MAT[3][2]: 1

INFORME MAT[3][3]: 1

INFORME MAT[3][4]: 1

INFORME MAT[3][5]: 1

INFORME MAT[4][0]: 1

INFORME MAT[4][1]: 1

INFORME MAT[4][2]: 1

INFORME MAT[4][3]: 1

INFORME MAT[4][4]: 1

INFORME MAT[4][5]: 1

INFORME MAT[5][0]: 1

INFORME MAT[5][1]: 1

INFORME MAT[5][2]: 1

INFORME MAT[5][3]: 1

INFORME MAT[5][4]: 1

INFORME MAT[5][5]: 1

A MATRIZ É QUADRADO MÁGICO!
...