Ошибка двойного освобождения или искажения при назначении строки

У меня возникают ошибки при назначении строки здесь. Это функция, которую мы закодировали для хранения данных, извлеченных из URL.
редактировать: структура datanode

  struct node
{
string url;
std::string* data;
struct node* next;
struct node* prev;
};void RandomCache::cachePage(string* page_data, string url)
{
datanode *page_node= (datanode*)malloc(sizeof(datanode));
page_node->url = url;
page_node->data = page_data;
page_node->next=NULL;
page_node->prev=NULL;

insertNode(page_node);

}

строка page_node-> url = url вызывает двойное освобождение или повреждение, данные передаются по значению, а не по ссылке. Кто-нибудь может указать, что идет не так?

Спасибо, я превратил структуру в класс, и проблема полностью решена. Спасибо! но я до сих пор задаюсь вопросом, почему управление структурой памяти с помощью malloc является проблематичным в C ++. структуры очень часто используются в c ++.

0

Решение

Ошибка двойного освобождения или искажения при назначении строки

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

В общем случае повреждение кучи часто обнаруживается после того, как реальное повреждение уже произошло некоторыми DLL / модулями, загруженными в ваш процесс. Но вполне возможно, что какой-то другой код делает что-то не так, и приведенный выше код является просто жертвой. Поэтому я бы порекомендовал вам использовать какой-то динамический инструмент, чтобы быстро понять ошибку и в тот момент, когда возникает проблема. Из вашего описания также возможно, что ваша программа имеет какое-то повреждение памяти.

Я думаю, что мой предыдущий пост может быть полезен и для этой проблемы. Если ваша программа специфична для Windows (WinDBG / PageHeap), вы должны увидеть следующую ссылку:

https://stackoverflow.com/a/22074401/2724703

Если ваша программа специфична для Gnu / Linux (Valgrind), вы должны увидеть следующую ссылку:

https://stackoverflow.com/a/22085874/2724703

1

Другие решения

Код, который вы показали, является абсолютно правильным C (и, следовательно, правильным C ++).

Q: Где хранится корень вашего дерева? Как переменная-член в классе «RandomCache», которая видна как «cachePage ()», так и «insertNode ()»? Глобальная переменная?

SUGGESTIONS:

1) убедитесь, что указатель datanode, для которого вы используете malloc () в вашей функции «cachePage ()», является так же Указатель у тебя на самом деле бесплатный. Из кода, который вы показали, возможно, что «datanode * page_node» имеет НЕТ видимость вне «cachePage ()» — и когда вы в конечном итоге «освободите ()» указатель, вы фактически освобождаете случайную неинициализированную память.

2) Valgrind может быть очень полезным здесь. Попытайся!

3) Всегда устанавливайте указатель на NULL после того, как вы его освободили.

1

Поскольку вы используете malloc вместо new, конструктор для datanode не будет вызываться, и, следовательно, std :: string в page_node-> url не будет вызывать свой конструктор .. Следовательно, page_node-> url будет испорчен когда вызывается его оператор равенства.

В частности, внутренне класс std :: string включает указатель на кусок памяти, который фактически содержит байты строки. Когда выполняется строковое присваивание, вызывается переопределенный оператор равенства для строки. Его первая задача — освободить существующую память для старой строки, которую должен был содержать объект. Если бы он был построен должным образом, он бы ничего не содержал, но здесь он будет просто содержать случайные данные, поэтому он уходит и освобождает некоторый случайный кусок памяти.

Решение состоит в том, что если вы хотите хранить строки (или любой класс C ++ с конструктором) внутри объекта, полностью сконструируйте объект и используйте new.

Попробуй это:

datanode *page_node= new datanode();

И замените ваш бесплатный () на удаление.

С другой стороны, у page_data другие проблемы. Когда вы передаете указатель на строку, расположенную в другом месте, вы должны быть осторожны с управлением памятью, чтобы исходная строка не выходила за пределы области действия или не уничтожалась, пока этот указатель может использоваться.

1
По вопросам рекламы [email protected]