Предотвратить изменение последнего элемента вектора char * - PullRequest
2 голосов
/ 19 октября 2010

Я читаю строки в C ++, используя fread, где я читаю и храню shortSiteText в siteNames_.siteNames_ объявлен как std::vector<char*> siteNames_; Я использую siteNames_ в других функциях, но поскольку shortSiteText является указателем, когда я вызываю команду удаления, последняя запись в siteNames_ изменяется.Как мне предотвратить это?

for (unsigned int i = 0; i <= nSites; i ++){
   fread((char *) &shortSiteTextLength, 1, sizeof shortSiteTextLength, baseFile_);
   shortSiteText = new char[shortSiteTextLength];
   fread(shortSiteText,1, shortSiteTextLength,baseFile_);
   siteNames_.push_back(shortSiteText);
}
delete [] shortSiteText;

Я попытался использовать оператор разыменования: siteNames_.push_back(*shortSiteText);, но это приводит к ошибке компилятора.

ПРИМЕЧАНИЕ: я должен использовать fread и char * из-за устаревшего кода.

Ответы [ 3 ]

3 голосов
/ 19 октября 2010

Вы не можете delete[] ничего нажимать на vector до тех пор, пока с ним не закончится связанный элемент vector.

Мне не ясно, какова цель этого кода - вы в любом случае удаляете только последнее использованное значение shortSitetext, так что это не делает то, что вы думаете (что пытается избежать утечки памятисопоставляя new с delete, я думаю).

Удалите последнюю строку кода и вручную очистите vector, когда закончите с ним, перебирая элементы, вызывающие delete[] для каждого, затем clear() vector.

Или используйте boost::ptr_vector, который сделает это автоматически.

Или используйте vector<string>, чтобы отделить устаревший код char* от вашего современного не необработанного указателя с использованием мира C ++.Вы можете нажать const char* прямо на vector<string> следующим образом:

const char* str;
// init str to the value you wish

vector<string> vec;
vec.push_back(str);
2 голосов
/ 19 октября 2010

Давайте увеличим это значение:

shortSiteText = new char[shortSiteTextLength];
siteNames_.push_back(shortSiteText);
delete [] shortSiteText;

Объяснение : Вторая строка просто выдвигает указатель на массив, а не сам массив. Затем в первой строке выделяется массив, на который все еще указывает последний элемент siteNames; это приводит к неопределенному поведению при использовании этого элемента.

Взломать : Удалить delete [] shortSiteText

Настоящее исправление : Вы сталкиваетесь с этой проблемой, потому что пытаетесь самостоятельно управлять владельцами объектов. Не надо! Здесь вы можете использовать std::string и по-прежнему иметь возможность работать с устаревшим кодом с помощью функции-члена c_str().

Процитирую моего друга:

Как правило, если вы начинающий, и ваш код содержит слово 'char', у вас есть ошибка.

0 голосов
/ 19 октября 2010

Не удаляйте shortSiteText, пока не захотите удалить данные из вектора.

Вы создали кусок памяти, задали данные и сохранили указатель в своем векторе. Память, которую вы удаляете, является той же самой памятью, на которую указывает элемент вектора.

Только что удалил строку delete [] shortSiteText;.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...