2013-03-24 6 views
-1

Найденное решениеОшибка памяти Weird C++. Const указатель изменяется

Описание проблемы: я использовал старую библиотеку C и имела класс, который получал константный символ * в качестве аргумента в функции. Эта функция создавала динамический объект и сохраняла его в связанном списке, используя const char * в качестве аргумента.

Проблема заключалась в том, что после этого const char *, который был передан функции, был изменен в памяти за пределами класса. Это уничтожило данные в узле.

Используйте std :: string как типы данных в классах. Когда const char * передается в строку как значение, строка берет на себя управление памятью для вас.

Что я узнал? При использовании C++ всегда используйте Strings и ТОЛЬКО используйте char * с string.c_str(), если это необходимо в некоторой библиотеке C.

Спасибо, ребята. Вы спасли мои выходные.

+3

Можете ли вы придумать гораздо меньший пример, демонстрирующий ту же проблему? Код, который вы связали, слишком велик для нас, чтобы выяснить, что с ним не так ... – Xymostech

+2

Попробуйте использовать valgrind. – mfontanini

+3

В этом случае ваш вопрос должен быть автономным, а не ссылкой на какой-либо внешний веб-сайт. Поэтому вам действительно нужно обрезать свой код и опубликовать соответствующий фрагмент, предпочтительно подходящий SSCCE (http://sscce.org). – hyde

ответ

1

buff создан в стеке. Вы передаете бафф в Cache.find, где в конце концов он становится ключом вашего узла. В следующий раз, когда вы обрабатываете соединение, память, занятая баффом, была повторно использована, потому что вы вышли из функции, в которой был объявлен бафф. Таким образом, ваш ключ исчезает/раздается. По сути, у вас есть указатели на память, которые больше не действительны.

Именно поэтому вы не должны пытаться катиться самостоятельно, а вместо этого используйте std :: map.

Кроме того, у вас есть несколько потоков, изменяющих глобальные переменные без какой-либо синхронизации.

+0

Я думаю, что это проблема. Я очень новичок в программировании на С ++, и я в основном не знаю, с чего начать. Если у меня есть const char *, как я могу скопировать его в новый const char *, который будет безопасен от несанкционированного доступа? –

+0

Нет, вы используете std :: string, тогда вам ** не нужно беспокоиться об этом **. Он будет обрабатывать память для вас. – john

+0

Большое спасибо. Это была моя проблема. У меня возникли проблемы с C-библиотекой, поэтому я попытался использовать char * как можно больше в программе. Изменение типов элементов на std :: string и простое восстановление string.c_str() полностью устранили проблему. –

0

Вы можете кипятить это намного дальше. Это, по моему мнению, от перехода от кода. По сути, то, что вы делаете это неверно:

const char* a; 
{ 
    std::string f("foo"); 
    a = f.c_str(); 
} 
doSomethingWith(a); 

Мой совет: отойти от char* полностью. Если есть места, где вы абсолютно должны их использовать, узнайте об объекте жизни объекта и о том, как сохранить указатель не продлевает это время жизни каким-либо образом. Я не имею в виду «не используйте char*, пока вы не поймете их лучше». Я думаю, что я понимаю их просто отлично и все же избегаю использовать их, когда смогу. Я имею в виду «использовать их, если вы работаете с кодом C (или кодом на C++, который в этом отношении выглядит как код C)».

Кроме того, вышеприведенные комментарии абсолютно верны. Обрежьте свою проблему насколько это возможно (это может дать вам ответ уже) и опишите это здесь, в автономном режиме.

Смежные вопросы