#arrays #c #parsing #struct #printf
#массивы #c #синтаксический анализ #структура #printf
Вопрос:
Я переписываю этот пост, потому что мне удалось разобраться в проблеме. Проблема с моим крайне прерывистым выводом была связана с неправильным динамическим выделением памяти.
По сути, мне нужно было выделить память для массива указателей, которые указывали на структуры, но сам массив был вложен внутрь другой структуры, и вложенность меня немного смутила, и в итоге я ее усложнил.
Итак, у меня была структура с именем Catalog, в которой находился мой массив, и этот массив указывал на другую структуру с именем Books .
Когда я изначально выделял для этого память, мне выделялась память только для массива, а не для массива указателей:
catalog->arrayP = malloc(INITIAL_CAPACITY * sizeof( Books );
// But I should have done this:
catalog->arrayP = (Books *) malloc(INITIAL_CAPACITY * sizeof( Books );
// That first (Books *) was extremely important
Вторая проблема, с которой я столкнулся, заключалась в том, что когда я пытался обновить память, чтобы разрешить больше книг, я фактически уменьшал ее:
catalog->arrayP = realloc(catalog->arrayP, 2 * sizeof( catalog->arrayP));
// I did this thinking it would just increase the memory to twice that of what it currently was, but it didn't
cataloc->capacity = catalog->capacity * 2;
catalog->arrayP = realloc(catalog->arrayP, catalog->capacity * sizeof( catalog->arrayP));
Поэтому всякий раз, когда мне нужно было увеличить свой массив указателей, я просто выделял достаточно памяти для 2 книг, а не удваивал текущую.
Комментарии:
1. @user3121023 Я попытался внести предложенные вами изменения, но теперь это вызывает ошибку сегментации 🙁
2. @user3121023 Существует malloc, но он использует книги, я обновлю вопрос, чтобы включить конструктор для каталога
3. Я предлагаю вам попробовать запустить инструмент проверки памяти valgrind в вашей программе. Вы могли бы использовать этот учебник .
4. @einpoklum Значит, я должен использовать sizeof (Книги) вместо этого, и у меня может быть утечка памяти в другом месте?
5. @JoshAvery: Возможно. Это общий совет, когда вы видите искаженные данные, которых вы не ожидали.
Ответ №1:
Frankenstein; Or, The Modern Prometh..Shelley, Mary Woll.
Ваши результаты печати как бы дают ответ. Вы забыли нулевой ограничитель в своих строках, и printf вторгся в следующее поле, пока не достиг нулевого ограничителя.
В следующих полях он не смог найти и вторгся еще больше материала.
Вот минимальный пример
#include <stdio.h>
#include <string.h>
struct test{
char test[37]; // space for 36 chars null
char test2[16]; // space for 15 chars null
};
int main(void) {
struct test Test;
strcpy(Test.test, "randomrandomrandomrandomrandomrandom"); // Copy the 37 bytes
strcpy(Test.test2, "notnotnotnotnot"); // Copy the 16 bytes
//Replace null terminator with trash for demonstration purposes
Test.test[36] = '1'; // replaces 37th byte containing the terminator () with trash
printf("8s", Test.test); // should print randomrandomrandomrandomrandomrandom1notnotnotnotnot
return 0;
}
Комментарии:
1. Это действительно устранило мою проблему с тем, что он продолжал печатать сверх того, что должен, но, к сожалению, я допустил ошибку при первоначальном создании сообщения. Я не включил весь вывод, что было ОГРОМНОЙ ошибкой с моей стороны, поскольку, если вы посмотрите на вывод сейчас, вы должны увидеть мою реальную проблему
2. Ошибка выглядит точно так же для меня. По-прежнему отсутствуют указатели null.
3. в выводимом тексте отсутствуют нулевые указатели? И это то, что приводит к тому, что вывод так ужасно нарушен? Я даже не знаю, куда бы я поместил больше нулевых терминаторов, у меня есть только 2 строки, которые я печатаю. Я попытался дважды проверить, что все строки заголовка и автора завершаются нулем, но это ничего не изменило.
4. О, я вижу, восклицание в названии Алисы. Хм, я думаю, вы в конечном итоге перезаписали вещи. Не могу помочь с этим без отладки. Я бы попробовал удалить эту быструю сортировку. Мои плохие, нулевые терминаторы, а не указатели. = x
5. Кстати, вы увеличили размеры MAX_TITLE и MAX_AUTHOR, чтобы освободить место для нулевого ограничителя?