#c #segmentation-fault
#c #ошибка сегментации
Вопрос:
Используя отладчик DevC (все еще новичок в нем), я почти уверен, что изолировал сценарий segfault, но я понятия не имею, почему это происходит.
void LinkedList::Add(const char *Word){
ListNode *newNode = new ListNode;
strcpy(newNode->Word, Word);
newNode->Next = NULL;
...
}
Ошибка сегмента возникает в «newNode-> Next = NULL;». Однако, если я удалю strcpy над ним, ошибка segfault не произойдет (но это означает, что мой newNode-> Word пуст)
РЕДАКТИРОВАТЬ: извините, ребята, вот ListNode:
struct ListNode
{
char *Word;
LNodePtr Next;
};
Комментарии:
1. Нам нужно увидеть определение ListNode.
2. Вероятно, эту проблему можно решить, если использовать
std::string
вместоchar *
для представления строк. В этом случае вы выполняете простое назначение.3. Можете ли вы опубликовать структуру
ListNode
?4. Для чего вы выделяете память
newNode->Word
?5. Хотя это и не вызывает проблемы, я изменю свой strcpy на strncpy(newNode-> Word, Word, cMaxLen); для безопасности. Спасибо за подсказку
Ответ №1:
Если Word
элемент является указателем, ваша strcpy
память перезапишет нераспределенную память.
После этого большинство операций может завершиться неудачей.
Использование std::string
вместо const char*
во многих местах спасет вас.
Комментарии:
1. Вы предполагаете, что в
ListNode
конструкторе дляWord
указателя не выделено памяти.2. @Naveen — Да, или недостаточно памяти. Просмотр
const char *Word
параметра просто заставляет меня поверить, что другойWord
выглядит так же. Тот факт, что он инициализирует элементы вAdd
, предполагает, что конструктор мало что делает.
Ответ №2:
Вы не выделили никакой памяти для Word
указателя в ListNode
структуре. Без этого он указывает на какое-то случайное местоположение, и всякий раз, когда вы пытаетесь выполнить запись в это местоположение (используя strcpy
), вы получите нарушение доступа. Самый простой способ решить эту проблему — использовать std::string
класс и избавиться от всего ручного управления памятью.
Если вы действительно хотите использовать char*
, то напишите конструктор, для ListNode
которого принимается const char*
параметр (не забудьте, однако, объявить его как explicit
) и используйте strlen
для определения длины входной строки. Затем выделите len 1
(дополнительный один char
для НУЛЕВОГО ограничителя) символы и сохраните адрес в Word
указателе. После этого вы можете сделать strncpy
.
Комментарии:
1. Теперь я вижу свою проблему, спасибо. К сожалению, мне пока придется придерживаться ручного управления памятью, поскольку это диктует мое назначение.
2. Я только что прочитал вашу правку, я попробую это! На данный момент просто добавьте «newNode-> Word = new char[cMaxLen]», прежде чем strncpy заработает. Значение cMaxLen равно 100. Я понимаю, что это делает бессмысленной динамичность, но это позволит мне пока поработать с остальной частью программы.
3. @Paul: не забудьте освободить память в деструкторе, иначе произойдет утечка.
Ответ №3:
strcpy
это нормально, но очень опасно, оно создает копию ваших символов, пока не достигнет
. Если ваш Word
файл не содержит никакого , он скопирует много материала в ваш newNode->Word
указатель.
Другая потенциальная опасность заключается в том, как вы инициализируете newNode->Word
, выделили ли вы достаточно места для копирования строки?
Ответ №4:
выдвигаю предположение.. Я бы рискнул предположить, что в вашей ListNode
реализации Word
это char*
, и оно не инициализировано для указания на допустимый блок памяти (может быть null) — strcpy()
не выделяет пространство автоматически, оно предполагает, что в месте назначения достаточно места. И здесь он пытается скопировать строку в нулевой указатель (или неинициализированный указатель) — отсюда ошибка segfault…