недопустимая ошибка realloc старого размера, чтение stdin - PullRequest
2 голосов
/ 13 апреля 2019

Я пытаюсь прочитать стандартный ввод. После достижения n символов перераспределите память, хотя есть 1 основная и 1 незначительная проблема. Ошибка перераспределения «недопустимый старый размер: 0x0000somenumers» возникает после 1 или 2 перераспределений и «ОШИБКА !!» не печатает Незначительная проблема заключается в том, что после нажатия клавиши ввода записывается номер символа.

int maxchar = 80;
char *buffer = (char *) malloc(sizeof(char) * maxchar);
int counter = 0;
char *tmp;

while((*(buffer + counter) = getchar()) != EOF){
    counter++;
    if(counter == maxchar - 1){
        tmp = (char *) realloc(buffer, sizeof(char) * (maxchar + maxchar));
        if(tmp == NULL){printf("MISTAKE!!!\n");break;}
        buffer = tmp;
        maxchar += maxchar;
        free(tmp);
        printf("Maxchar is now: %d\n", maxchar);
    }
}

buffer[counter] = '\0';
// some operations

printf("%s\n", buffer);

Ответы [ 2 ]

2 голосов
/ 13 апреля 2019

с заданием

buffer = tmp

у вас есть два указателя, указывающих на одну и ту же память. Это можно посмотреть примерно так:

   +-----+
   | tmp | --\ 
   +-----+    \     +--------------------------------+
               >--> | memory allocated by realloc... |
+--------+    /     +--------------------------------+
| buffer | --/
+--------+

Поскольку у вас есть только одно выделение, вызов

free(tmp);

освободит это единственное распределение. После этого звонка на free у вас есть что-то вроде

   +-----+
   | tmp | --\ 
   +-----+    \     +-----------------------+
               >--> | unallocated memory... |
+--------+    /     +-----------------------+
| buffer | --/
+--------+

Это означает, что любое разыменование buffer будет недопустимым, поскольку также указывает на эту нераспределенную память. И, конечно, любой дальнейший вызов realloc также недопустим, поскольку перераспределять нечего.

Решение простое: не вызывайте free в цикле.

0 голосов
/ 13 апреля 2019

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

Обратите внимание, что sizeof(char) всегда 1.

int maxchar = 80;
char *buffer = malloc(sizeof(char) * maxchar);
int counter = 0;

int c;
while ((c = getchar()) != EOF){
    *(buffer + counter) = c;
    counter++;

    if (counter == maxchar - 1) {
        maxchar += maxchar;
        char *tmp = realloc(buffer, sizeof(char) * maxchar);
        if (tmp == NULL) {
            printf("MISTAKE!!!\n");
            break;
        }
        buffer = tmp;
        printf("Maxchar is now: %d\n", maxchar);
    }
}

buffer[counter] = '\0';
// some operations

printf("%s\n", buffer);

free(buffer);

Я вижу, что вы сделали не так, здесь.Вы должны освобождать указатель только тогда, когда вы закончите с памятью, на которую он указывает , а не когда вы закончите с самим указателем.Только free ваша последняя копия указателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...