ошибка bad_alloc при использовании std :: string - PullRequest
3 голосов
/ 07 октября 2008

В настоящее время я работаю над проектом, который зависит от моего пути к файлу (например, C:\Path.pth). Теперь у меня все работало вчера, позвонив моему std::string с:

std::string path(`"C:\\Path.pth`");

Но теперь это не работает. Это бросает bad_alloc. Кажется, проблема в символе \. Я даже попытался использовать \x5C в качестве значения ascii, но тот же результат.

Теперь мой вопрос: возможно ли, что я облажался с какой-то #define, какой-то опцией компилятора или с чем-то еще, не связанным с кодом, что могло вызвать это? Я использую VS 2005.

Любая помощь будет высоко ценится


PierreBdR

.. Это звучит очень вероятно. Или, по крайней мере, это должно: P

Поскольку никто не упомянул какую-либо опцию / SetStringCharSize: 2bit-compiler, я думаю, можно с уверенностью предположить, что мой код должен что-то испортить, где-то, и что это не просто глупая опция компилятора (или подобная) это неправильно ..

Ответы [ 6 ]

6 голосов
/ 07 октября 2008

Как показывает ваша ошибка, проблема связана с выделением памяти (т.е. исключение bad_alloc).

Так что либо у вас больше нет памяти (маловероятно), либо у вас было переполнение буфера где-то раньше (вполне вероятно, на мой взгляд), либо некоторые другие проблемы с памятью, такие как double free.

Короче говоря, вы делаете что-то, что портит структуру управления памятью (то есть всю эту информацию между выделенными блоками). Проверьте, что происходит до этого вызова.

3 голосов
/ 07 октября 2008

Ошибка найдена и исправлена.

Похоже, что TinyXML имел ошибку при использовании с определением TIXML_USE_STL. По какой-то причине конструктор TiDocument настолько испортил мой макет памяти, что следующее определенное мной std::string должно вызвать исключение bad_alloc - и, к счастью для меня, именно на 4-м символе строки, в моей ситуации было '\', что привело к довольно тонкой ошибке.

1 голос
/ 07 октября 2008

Не забывайте, вы должны использовать косую черту в путях, даже в Windows:

[15.16] Почему я не могу открыть файл в другом каталоге, например ".. \ test.dat"?

Поскольку "\ t" является символом табуляции.

Вы должны использовать прямую косую черту в именах файлов, даже в операционных системах, которые используют обратную косую черту (DOS, Windows, OS / 2 и т. Д.). Например:

#include <iostream>
#include <fstream>

int main()
{
  #if 1
    std::ifstream file("../test.dat");  // RIGHT!
  #else
    std::ifstream file("..\test.dat");  // WRONG!
  #endif

  ...
} 

Помните, что обратная косая черта ("\") используется в строковых литералах для создания специальных символов: "\ n" - это новая строка, "\ b" - это обратный пробел, а "\ t" - это вкладка, "\ a "является" предупреждением "," \ v "является вертикальной вкладкой и т. д. Поэтому имя файла" \ version \ next \ alpha \ beta \ test.dat "интерпретируется как набор очень забавных символов. Для безопасности используйте вместо этого «/version/next/alpha/beta/test.dat», даже в системах, которые используют «\» в качестве разделителя каталогов. Это потому, что библиотечные подпрограммы в этих операционных системах обрабатывают "/" и "\" взаимозаменяемо.

Конечно, вы могли бы использовать "\\ version \\ next \\ alpha \\ beta \\ test.dat", но это может повредить вам (есть ненулевой шанс, что вы забудете один из "\" s, довольно тонкая ошибка, так как большинство людей не замечают ее), и она не может помочь вам (нет смысла использовать «\» над «/»). Кроме того, «/» более переносим, ​​поскольку он работает на всех версиях Unix, Plan 9, Inferno, на всех Windows, OS / 2 и т. Д., Но «\» работает только на подмножестве этого списка. Так что «\» вам чего-то стоит и ничего не дает: вместо этого используйте «/».

(из C ++ FAQ Lite )

0 голосов
/ 07 октября 2008

Если ваш двойной обратный слеш верен, я думаю, вы работаете в Vista?

По умолчанию Vista не разрешает вашу запись в корневой каталог диска C. Попробуйте одно из следующего:

  • Отключить UAC или
  • Запустите ваше приложение как «Администратор» или
  • Запись в подкаталог.
0 голосов
/ 07 октября 2008

Нет, у вас вчера тоже не было "работы". '\' нужно экранировать так:

std::string path("c:\\path.pth");

Вы, вероятно, вчера сделали косую черту, которая также может работать в этой ситуации.

std::string path("c:/path.pth");
0 голосов
/ 07 октября 2008

Определить строку как: "C: \\ Path.pth"

...