Почему это всегда показывает ошибку: указатель, являющийся reallo c, не был выделен - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь прочитать из файла и поместить указатели каждой строки в «стек» двойного указателя, но всегда не удается восстановить c его. Может быть, я должен использовать тройной указатель ????

int i = 1;
char * line = malloc(BUFSIZ);
char ** stack;
stack = (char ** ) malloc(sizeof(char * ));

while (fgets(line, BUFSIZ, file) != NULL) {
    stack = & line;
    printf("//%s", line);
    printf("??%s", * stack);
    i++;
    stack = (char ** ) realloc(stack, sizeof(char * ) * i);
}

Ответы [ 2 ]

1 голос
/ 08 января 2020

Для начала код имеет утечку памяти. Сначала была выделена память

stack = (char ** ) malloc(sizeof(char * ));

, а затем указатель stack был переназначен с адресом указателя line.

while (fgets(line, BUFSIZ, file) != NULL) {

stack = & line;
//…

Этот оператор

stack = (char ** ) realloc(stack, sizeof(char * ) * i);

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

stack = & line;

не указывает на динамически выделенную память. Он указывает на локальную переменную line.

. Кажется, вы пытаетесь сделать следующее, как показано в демонстрационной программе ниже. Только вместо файла используется стандартный поток ввода stdin.

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

int main(void) 
{
    char *line = malloc( BUFSIZ );
    char **stack = NULL;
    size_t n = 0;

    while ( fgets( line,BUFSIZ, stdin ) != NULL )
    {
        line[strcspn( line, "\n" )] = '\0';

        char **tmp = realloc( stack, ( n + 1 )* sizeof( char * ) );

        if ( tmp != NULL )
        {
            stack = tmp;
            ++n;

            stack[n-1] = malloc( BUFSIZ );

            if ( stack[n-1] != NULL ) strcpy( stack[n-1], line );
        }
    }

    for ( size_t i = 0; i < n; i++ )
    {
        if ( stack[i] != NULL ) puts( stack[i] );
    }

    for ( size_t i = 0; i < n; i++ )
    {
        free( stack[i] );
    }
    free( stack );

    free( line );

    return 0;
}

Если ввести две строки

Hello
World

, тогда вывод будет

Hello
World
1 голос
/ 08 января 2020

Вы получаете это сообщение об ошибке, потому что вы установили stack на адрес line. Как следствие, stack больше не является выделенным блоком.

В вашем коде есть несколько ошибок.

  • Вы должны сохранить строку в стеке по индексу i
  • Вы должны выделить новый блок для каждой строки
  • Вы должны перераспределить для i + 1 строки, чтобы создать место для следующей строки, если она есть

Вот исправленный код:

int i = 0; // number of line pointers in the stack
char *line = malloc(BUFSIZ);
char **stack = malloc(sizeof(char*));
while( fgets(line, BUFSIZ, file) != NULL) {
    stack[i] = line;
    printf("//%s", line);
    printf("??%s", stack[i]);
    i++;
    line = malloc(BUFSIZ); // allocate a new block for the next line
    stack = realloc(stack, sizeof(char*)*(i+1)); // make room for the next line
}
...