Ошибка сегментации 'C' с 2d массивом

Кто-нибудь может объяснить мне, почему этот код не работает?

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

void findAndPrint(char *arr[], int year, int month, int day);

int main()
{
    char *dayTab[] = {
        {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };
    findAndPrint(dayTab, 3, 3, 3);
    getchar();
    return 0;
}

void findAndPrint(char *arr[], int year, int month, int day ){
    int d = 0;
    if(month > 12 || month < 1 || day > 31 || day<1)
        return;
    int leap = ((year%4==0 && year%100!=0) || year%400 == 0)?1:0;
    int i;
    for(i=0; i<month-1; i++){
        d += arr[leap][i];
    }
    d+= day;
    printf("Day = %d", d);
}

IDE (Code:: Blocks) пишет "Программа получила сигнал SIGSEGV. Ошибка сегментации."

2 ответа

Решение

Во-первых, вам нужен двумерный массив символов, а не массив указателей на символы.

char dayTab[][12] = {
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

Затем вы должны изменить функцию, чтобы принять этот тип.

void findAndPrint(char arr[][12], int year, int month, int day ) ;

Остальное выглядит хорошо.

Попытка с параметрами:

findAndPrint(dayTab, 2014, 10, 12);

Дает нам день: 285

Что правильно, даааа!

Если я правильно понял ваше намерение, вы хотели, чтобы эти вложенные {31, 28, ... } последовательности, чтобы служить char[] массивы, на которые будут указывать указатели в массиве верхнего уровня.

Несмотря на то, что говорится в другом ответе (ответах), неверно говорить, что вам обязательно нужен буквальный двухмерный массив (хотя в этом случае двухмерный массив может быть лучшей идеей, чем то, что вы пытались сделать). Ваша оригинальная попытка будет работать, если вы используете правильный синтаксис.

Теперь вы не можете просто посадить {31, 28, ... } последовательность в середине кода и ожидать, что компилятор интерпретирует его как массив. В языке нет такой возможности, но есть похожий с немного другим синтаксисом. Единственный способ добиться правильной инициализации вашего char *dayTab[] Массив в этом "встроенном" стиле должен использовать составную буквальную особенность. Инициализация будет выглядеть следующим образом

char *dayTab[] = {
    (char []) { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    (char []) { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};

Обратите внимание на дополнительные (char []) синтаксис. Это абсолютно необходимо. Это единственное, что вам нужно изменить в исходном коде, чтобы он компилировался так, как задумано.

То, что вы в настоящее время имеете в своем исходном коде, недопустимо C. Если какой-то компилятор принял этот код (GCC в CodeBlocks?), То только из-за некоторого расширения компилятора. Это расширение компилятора сыграло с вами злую шутку в данном конкретном случае. Я даже не знаю, как это интерпретировалось компилятором, но определенно не так, как вы хотели, чтобы это интерпретировалось.

PS В моих экспериментах GCC дал стену диагностических сообщений в ответ на наш оригинальный код. Вы получили эти сообщения от вашего компилятора? Вы просто игнорировали их?

Другие вопросы по тегам