Ядро сбрасывается на текст realloc выше 26 символов c - PullRequest
0 голосов
/ 28 декабря 2018

Мне нужно соединиться со своим собственным протоколом с сервером и некоторыми телескопами, отправляющими данные.После того, как общение завершено, я разделил сообщение, чтобы узнать, в каком случае это происходит.Подключение и отключение работают нормально, но при разбиении данных создается дамп ядра ( realloc (): недопустимый следующий размер ).

Connection отправляет это сообщение: 0x01[]10[Telescope1]
Disconnection отправляет это сообщение: 0x02[]10[Telescope1]
При отправке данных отправляется это сообщение: 0x03[METADATA]22[.txt&15&someRandomDate]

Я намерен разбить эти сообщения на тип (0x03), заголовок (METADATA), длина поля данных (22) и data (.txt & 15 & someRandomDate).

После некоторого тестирования я пришел к выводу, что это связано с размером строки.Для отладки при отправке данных я использовал вместо этого сообщение о соединении, и разбиение работало бы нормально (каждое поле возвращалось правильно).

Затем я постепенно изменил бы его значение char на char на то, что предполагается разделить, и разделил бы это сообщение нормально 0x03[METADA]10[Telescope1] (размер 26), но не 0x03[METADAT]10[Telescope1] (размер 27).Во втором случае он вывел бы следующее:

string to split: 0x03[METADAT]10[Telescope1]
copying type 0
realloc of size 1
copying type x
realloc of size 2
realloc(): invalid next size
Aborted (core dumped)

Таким образом, он зашёл бы так далеко, что прочитал бы 0x, и они пошли бы в дамп ядра.Кроме того, ядро ​​будет сброшено, если я сделаю строки подключения или отключения больше 27 символов, добавив случайный текст внутри сообщения.

Вот мой код для разделения строки.Это довольно плохо, так как я всегда борюсь с malloc и reallocs, поэтому извините заранее.

Data read_data (char* string){
printf("string to split: %s\n", string);
Data d;
int i = 0;
char *aux = (char *) malloc(1);

while (string[i] != '[' || string[i] == '\0'){

    printf("copying type %c\n", string[i]);
    printf("realloc of size %d\n", (i + 1));
    aux = (char *) realloc(aux, (i + 1));
    //here also tried aux = (char *) realloc(aux, (i + 1) * sizeof(char*)); didn't work
    strcpy(&aux[i], &string[i]);
    i++;
}
aux[i] = '\0';
d.type = aux[3];

i++;

int j = 0;
aux = (char *) malloc(1);
while (string[i] != ']' || string[i] == '\0'){
    printf("copying header %c\n", string[i]);
    aux = (char *) realloc(aux, j + 1);
    strcpy(&aux[j], &string[i]);
    i++;
    j++;
}
aux[j] = '\0';
d.header = aux;

i++;

j = 0;
aux = (char *) malloc(1);
while (string[i] != '[' || string[i] == '\0'){
    printf("copying size %c\n", string[i]);
    aux = (char *) realloc(aux, j + 1);
    strcpy(&aux[j], &string[i]);
    i++;
    j++;
}
aux[j] = '\0';
d.length = atoi(aux);

i++;
j = 0;
aux = (char *) malloc(1);
while (string[i] != ']' || string[i] == '\0'){
    printf("copying data %c\n", string[i]);
    aux = (char *) realloc(aux, j + 1);
    strcpy(&aux[j], &string[i]);
    i++;
    j++;
}
aux[j] = '\0';
d.data = aux;
return d;
}

Как я могу это исправить?Почему это работает нормально, если это более короткая строка?

EDIT : Как указывал Spikatrix, если я использую aux[i] = string[i]; вместо strcpy(&aux[i], &string[i]);, то отлично работает

1 Ответ

0 голосов
/ 28 декабря 2018

Сообщение об ошибке realloc (): неверный следующий размер в основном говорит о том, что куча была повреждена (до вызова realloc()).Таким образом, проблема не в realloc , а в другом коде.

И на первый взгляд виновным является следующее утверждение:

strcpy(&aux[i], &string[i]);

Возможно, вы хотите скопировать одинсимвол до конца aux .Но это делает что-то совершенно другое.Он копирует строку - начиная с позиции i и до конца строку - в aux начиная с позиции i .Однако aux имеет длину всего i + 1 символов.Таким образом, эта операция записывает вне выделенной строки и повреждает кучу.

Лучше отбросить весь код.Это излишне сложно и неэффективно.Используйте strchr , чтобы найти соответствующие символы (открывающие и закрывающие скобки).Тогда вы знаете позицию и можете легко скопировать соответствующую подстроку.

...