Почему вылезает Segmentation fault (core dumped)?

Рейтинг: 0Ответов: 1Опубликовано: 18.04.2023

Начала писать программу, где в самом начале пользователь должен ввести 1 аргумент командной строки в виде положительного числа. При вводе чего угодно кроме ./caesar выдает Segmentation fault (core dumped). Пробовала без вызова функции only_digits внутри main прописывать тот же цикл, тогда все работает как надо. Но в задаче стоит создать эту функцию. Есть подозрения, что проблема возникает из-за того, что я вообще не понимаю, что эта функция должна возвращать (запуталась с нулями и единицами). Но я пробовала и return 0, и return 1 - исход одинаковый. Помогите разобраться, пожалуйста...

#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int only_digits(string argv[1]);

int main(int argc, string argv[])
{
    // If the number of CLA is more or less than two
    if (argc != 2)
    {
        printf("User: ./caesar key\n");
        return 1;
    }

    int digit = only_digits(&argv[1]);

    string plaintext = get_string("Please enter the message you want to code here: ");

}

int only_digits(string argv[1])
{
    // If the 2nd CLA is not an integer
    for (int i = 0; i < strlen(argv[1]); i++)
    {
        if (isdigit(argv[1][i]) == 0)
        {
            printf("User: ./caesar key\n");
            return 1;
       }
    }
    return 1;
}

Ответы

▲ 2Принят

В

 int digit = only_digits(&argv[1]);

вы передаёт указатель на аргумент. А в функции вы добавляете ещё раз индекс [1]

strlen(argv[1])

Локальная переменная argv уже указывает на первый элемент и дополнительное смещение укажет на нулевой указатель. Происходит крах памяти.

Подробнее в функции main так :

argv [ ] = [0] = адрес0 , [1] = адрес1 , [2] = адрес2

адрес0 = "има проги"
адрес1 = "аргумент"
адрес2 = нулевой указатель

& argv [ 1 ] == & адрес1

а в only_digits локальная переменная :

argv == & адрес1
argv + 1 == & адрес2
argv [ 1 ] == адрес2

Простое решение - поменять индекс на ноль :

int only_digits(string argv[])
{
    // If the 2nd CLA is not an integer
    for (int i = 0; i < strlen(argv[0]); i++)
    {
        if (isdigit(argv[0][i]) == 0)
        {
            printf("User: ./caesar key\n");
            return 1;
       }
    }
    return 1;
}

А лучше передавать не указатель на массив строк, а указатель на одну строку.

int only_digits(string argv);

int main(int argc, string argv[])
{
    // If the number of CLA is more or less than two
    if (argc != 2)
    {
        printf("User: ./caesar key\n");
        return 1;
    }

    int digit = only_digits(argv[1]);

    //string plaintext = get_string("Please enter the message you want to code here: ");
  string plaintext = "привет" ;
}

int only_digits(string argv)
{
    // If the 2nd CLA is not an integer
    for (int i = 0; i < strlen(argv); i++)
    {
        if (isdigit(argv[i]) == 0)
        {
            printf("User: ./caesar key\n");
            return 1;
       }
    }
    return 1;
}