简体   繁体   中英

'C' Segmentation fault with 2d array

Can anybody explain me why this code doesn't work?

#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) writes "Program received signal SIGSEGV. Segmentation fault."

First you need a 2d array of characters, not an array of pointers to characters.

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}
};

Then you have to change the function to accept that type.

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

The rest looks ok.

Trying with parameters:

findAndPrint(dayTab, 2014, 10, 12);

Gives us day: 285

Which is correct, yaaay!

If I properly understood your intent, you wanted those nested {31, 28, ... } sequences to serve as char[] arrays, to which the pointers in the upper level array would point to.

Despite what the other answer(s) states, it is not correct to say that you necessarily need a literal 2D array (even though in this case a 2D array might be a better idea than what you attempted to do). You original attempt will work too, as long as you use the proper syntax.

Now, you can't just plant a {31, 28, ... } sequence in the middle of the code and expect the compiler to interpret it as an array. The language does not have such feature, but it has a similar one with slightly different syntax. The only way achieve the proper initialization of your char *dayTab[] array in that "inline" fashion is to use the compound literal feature. The initialization will look as follows

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 }
};

Note the extra (char []) syntax. This is absolutely necessary. This is the only thing that you have to change in your original code to make it compile as intended.

What you currently have in your original code is not valid C. If some compiler accepted this code (GCC in CodeBlocks?), then only due to some compiler extension. That compiler extension happened to play a cruel joke on you in this particular case. I don't even know how it was interpreted by the compiler, but definitely not how you intended it to be interpreted.

PS In my experiments, GCC gave a wall of diagnostic messages in response to our original code. Did you get those messages from your compiler? Did you just ignore them?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM