C ++ Хранение копии строки в векторе пар - PullRequest
1 голос
/ 10 октября 2010

У меня есть закрытый атрибут в классе, который определен как vector<pair<char *, int> > data;. Я добавляю данные к этому вектору с data.push_back(make_pair(p, r));. Позже, когда я получаю данные из вектора, я получаю неверные данные для значения p. Возвращенные данные похожи на ��U3. Я думаю, что это потому, что указатель на массив символов сохраняется. Как бы я сохранил фактическую копию в векторе. Если это поможет, массив символов никогда не превысит 255 символов + 1 для нулевого завершения.

Ответы [ 5 ]

5 голосов
/ 10 октября 2010

Есть ли реальная причина для использования char*?

Используйте std::string, и ваши проблемы исчезнут.

1 голос
/ 10 октября 2010

Вы распределяете строку через переменную стека и сохраняете ее адрес?Это может вызвать проблему, которую вы описываете, когда вы возвращаетесь из функции, в которой вы размещаете.

Лучше выделить строку в куче (с новым оператором), а затем сохранить выделенный адрес кучи.например,

char* pNext = new char[50];
strcpy(pNext, ...);
data.push_back(make_pair(pNext, r));

Вы должны выполнить всю свою собственную работу с массивами символов -eg. Вы должны убедиться, что они обнулились, иначе вы получите непредвиденные результаты при их печати. ​​

например,

pNext[49] = '\0';

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

delete [] pNext;

Как уже говорили другие, есть другие реализации строк, которые вызовут у вас меньше головной боли.

Самым простым в использовании, вероятно, является CString, но он требует дополнительных затрат, включая реализацию MFC или реализацию ATL.std :: string, как уже упоминали другие, являются альтернативой.

надеюсь, это поможет!

1 голос
/ 10 октября 2010

Если у вас есть vector<pair<char *, int> >, вы имеете дело с голыми указателями, и необходимо вручную управлять временем жизни ваших строк .Это важный PITA, и очень вероятно, что вы делаете что-то не так (особенно если учесть, что вы даже не удосужились заявить, что делаете это правильно, что, по-видимому, подсказываетдаже не знаю, что вы должны это сделать).

Как и другие, я бы посоветовал вам использовать vector<pair<std::string, int> >.

1 голос
/ 10 октября 2010

Поскольку STL основан на семантике копирования и значения, проще, если вся строка символов, а не просто указатель на нее, хранится в контейнере (здесь vector).Я сказал «проще», потому что можно хранить указатели в контейнерах STL, но затем указанная память должна управляться кодом пользователя.Из вопроса, похоже, что это не было сделано.

Итак, возможно, вы можете использовать string вместо char *, например:

typedef std::pair< std::string, int > MyPair;
std::vector< MyPair > data;
1 голос
/ 10 октября 2010

Похоже, у вас есть указатель на p (который определен в то время), помещенный в стек.После того, как кадр стека извлечен, у вас все еще есть указатель, но память, на которую он указывает, может быть мусором.Подобные проблемы с висящими указателями могут раздражать, поэтому я рекомендую использовать класс std :: string, определенный в #include <string>, для хранения строковых данных.

...