Supongamos que tenemos la tarea de escribir una función que sume 2 números.

#include <stdio.h>

int main(int argc, char ** av) {
    int a = atoi(av[1]);
    int b = atoi(av[2]);
    add_and_print(a, b)
    return 0;

}

Funciona bien hasta que pase el siguiente código:

./a.out

Simplemente pasando cuerdas vacías. Luego escribe lo siguiente:

1495 segmentation fault (core dumped)

¿Podría explicar cuál es el problema y cómo lo soluciono?

c
0
Rustem Sadykov 22 abr. 2020 a las 17:05

2 respuestas

La mejor respuesta

¿Cómo trato con segfault

El segfault ocurre debido a un error en su código.

Entonces, evitas que ocurra en primer lugar, al no escribir código con errores.

Sin embargo, en general, el segfault hace que sea fácil descubrir exactamente qué error lo activó: simplemente ejecute su programa bajo el depurador, y se detendrá exactamente donde ocurre el segfault.

¿Podría explicar cuál es el problema?

En este código:

int a = atoi(av[1]);

La expresión av[1] solo es legal si hay al menos dos elementos en la matriz av (ya que comenzamos a indexar en cero). Si solo hay un elemento, este código intenta leer más allá del final de la matriz.

Dado que la matriz se basa en los argumentos de la línea de comandos, debe verificarla . Debe hacer esto para todas entradas de usuarios, archivos e incluso otras partes de su propio código. No asuma que el usuario hizo lo que esperaba (o que el archivo contenía lo que esperaba o que la persona que llamó pasó los valores correctos). Esto es un error

if (argc >= 2) {
    // now it is safe to refer to av[1]
    a = atoi(av[1]);
}

Tienes que hacer algo similar para av[2], por la misma razón.

Una solución común podría ser en su lugar

int main(int argc, char **argv) {
    if (argc < 3) {
        printf("Syntax: %s a b\n"
               "\n"
               "Two integer arguments are required.", argv[0]);
        return -1;
    }
    int a = atoi(argv[1]);
    int b = atoi(argv[2]);
    add_and_print(a, b)
}

Solo estoy asumiendo que argc es al menos 1, y que argv[0] es el nombre del programa. También puede verificar esto si desea un código perfectamente portátil.

Tenga en cuenta que es posible que también desee comprobar si los argumentos son realmente enteros.

2
Useless 22 abr. 2020 a las 21:13

argc contiene el número de argumentos proporcionados al programa, y si no lo verifica, es posible que obtenga una falla predeterminada al intentar leer desde argv. Puede mostrar un mensaje de error y salir si no hay suficientes argumentos:

if (argc < 3) {
    puts("Please provide 2 numbers as command line arguments.");
    return 1;
}
3
Aplet123 22 abr. 2020 a las 14:12