Запись в массив символов, который является членом структуры - PullRequest
0 голосов
/ 18 февраля 2010

я впервые публикую здесь вопрос - я искал похожие, но не нашел ничего, что нашел.

Вот фрагмент из моего заголовка:

#define LINE_LEN_MAX 256

typedef struct line_description {
    char buffer[LINE_LEN_MAX + 1];
    [...]
} line;

А вот фрагмент из моей основной функции:

int main(int argc, char *argv[]) {

    line *lineRead;

    //input: valid FILE *, read from cmdline
    //char buffer[LINE_LEN_MAX + 1];

    while(fgets(lineRead->buffer, LINE_LEN_MAX + 1, input) != NULL) {

        [...]

        memset(lineRead->buffer, 0, LINE_LEN_MAX + 1);
    }
}

Я получаю сегфо. Если я закомментирую строку 'memset ()', я смогу прочитать ровно 3 строки из моего входного файла перед тем, как получить ошибку сегмента.

Однако, если я заменим 'lineRead-> buffer' на локальный символ [], я смогу отлично прочитать мой входной файл.

Что я не понимаю о структурах здесь? Я думаю, что мне нужен указатель на начало char [] внутри структуры, но, очевидно, это не то, что происходит.

РЕДАКТИРОВАТЬ: Извините, забыл указать: я не использую динамическую память здесь.

Ответы [ 3 ]

2 голосов
/ 18 февраля 2010

lineRead в вашей программе - неинициализированный указатель, что, вероятно, не то, что вы хотели.

Вы должны выделить некоторое место для хранения строки, написав, например, line lineRead, что выделит line структура в стеке.Затем используйте . вместо -> для доступа к своим членам.

1 голос
/ 18 февраля 2010

Может быть, вы просто что-то упустили из своего фрагмента, но не показали выделенную структуру.

line *lineRead; // uninitialized pointer: access to any field crashes
lineRead = (line*) malloc( sizeof( line_description ) );

Или, если вам не нужно, чтобы это было в куче (особенно учитываячто объект стека в самой внешней области действия в main в любом случае имеет время жизни всей программы),

line lineRead; // don't need to use a pointer!
1 голос
/ 18 февраля 2010

Вы объявляете lineRead указателем на line, но на самом деле вы не устанавливаете его, чтобы указывать на что-либо.Затем, когда вы пытаетесь получить доступ к случайному местоположению, на которое указывает неинициализированный указатель, вы получаете ошибку сегментации.

Если вам требуется только lineRead в локальной области, это не должен быть указатель, простообъявите его как

line lineRead;

Если lineRead должен жить дольше, чем функция, и поэтому действительно должен динамически выделяться, используйте указатель, но также зарезервируйте память для структуры, на которую она должна указывать:

line *lineRead = malloc(sizeof(line));
lineRead->buffer[0] = '\0'; // or any other initializations...
...