C99 командная строка ничего не печатает в этом случае программирования C - PullRequest
2 голосов
/ 25 октября 2011

У меня сегодня странная проблема с Си. Взгляните на этот упрощенный фрагмент кода:

typedef struct
{
    /* The number of index terms */
    int nTerms;
    /* Information about each index term */
    TERMINFO *terms;
} INDEX;

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts)
{
    INDEX *ind = NULL;
    ind->nTerms = 5;
    return ind;
}

int main(int argc, char *argv[]) {
    ... // declare and assign values for TERMFILE, DIRS and opts.
    INDEX *ind = buildIndex(TERMFILE, DIRS, sizeof(DIRS), opts); // LINE A 
    printf("Does NOT print %d\n",ind->nTerms); // LINE B
    printf("Does NOT print as well"); // LINE C
    return 0;
}

Когда я компилирую эту программу, ошибок не возникает, однако, когда я запускаю скомпилированный файл, он ничего не печатает в командной строке (я использую PuTTy на машине с Windows). Становится даже странно, когда я удаляю строки LINE A и LINE B, тогда можно напечатать LINE C.

Короче говоря, все, что идет после LINE A, не может быть распечатано (или выполнено?).

Я не знаю, есть ли проблемы с моим кодом.

Ответы [ 4 ]

4 голосов
/ 25 октября 2011

Во второй строке вы разыменовываете указатель NULL, что приводит к неопределенному поведению:

INDEX *ind = NULL;
ind->nTerms = 5;
return ind;

Вам необходимо ind указать на нелокальную память, т.е. выделить ее изкуча с malloc, или установите его так, чтобы он указывал на переменную с глобальным временем жизни:

INDEX *ind = malloc(sizeof(INDEX));

if (ind != NULL)
    ind->nTerms = 5;

return ind;

Ответственность за освобождение возвращаемой структуры (и не разыменовывать ее, если она NULL) делегируется вызывающей стороне в этомcase.

Обратите внимание, что если вы установите ind, чтобы указать на локально объявленную переменную и вернуть ее, UB будет появляться всякий раз, когда вызывающая сторона пытается разыменовать указатель, потому что стек восстанавливается после функциизавершается.

4 голосов
/ 25 октября 2011

Причина, по которой он ничего не печатает, заключается в том, что происходит сбой:

INDEX *ind = NULL;
ind->nTerms = 5;

Вы разыменовываете NULL.(что является неопределенным поведением)

Когда вы удаляете LINE A и LINE B, он не падает, поэтому печатается LINE C. (Вы также забыли \n в LINE C, чтобы очистить буфер.)

Что вам нужно сделать, это динамически выделить ind через malloc и return.(и обязательно освободите его позже)

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts)
{
    INDEX *ind = malloc(sizeof(INDEX));   //  Allocate

    //  You may wish to check if `ind == NULL` to see if the allocation failed.

    ind->nTerms = 5;
    return ind;
}

int main(int argc, char *argv[]) {
    ... // declare and assign values for TERMFILE, DIRS and opts.
    INDEX *ind = buildIndex(TERMFILE, DIRS, sizeof(DIRS), opts); // LINE A 
    printf("Does NOT print %d\n",ind->nTerms); // LINE B
    printf("Does NOT print as well"); // LINE C

    free(ind);  //  Free

    return 0;
}
1 голос
/ 25 октября 2011

Кажется, ваша проблема в buildIndex

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts) 
{
    INDEX *ind = NULL;
    ind->nTerms = 5;
    return ind; 
}

Как видите, вы устанавливаете ind на NULL, а затем сразу же пытаетесь сослаться на него. Это неопределенное поведение, поэтому все может произойти дальше.

0 голосов
/ 25 октября 2011

Вы вызываете функцию buildIndex, которая содержит эти две строки.

INDEX * ind = NULL; ind-> nTerms = 5;

Итак, вы разыменовываете нулевой указатель. Это ошибочно Ваша программа вылетает, поэтому больше не запускайте.

...