Ни насколько не допустимо. К тому же, mfn.size() в данном случае 0.
D>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?
Это тебе кажется, что "по уму", а мне кажется, что есть стандарт языка, и в нём непрерывность гарантируется только для std::vector (и для std::string::c_str(), но этот метод возвращает константный указатель, который теоретически не обязан совпадать с собственно внутренним буфером строки).
D>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?
Дело в том, что непрерывность массива символов гарантирована только для указателей, возвращаемых при вызове data() и c_str(), но при этом сами массивы доступны только для чтения. Это вроде как было сделано в древние времена чтобы позволить использовать в реализациях ::std::string всякие хитрые приемы (типа copy on write) для снижения количества копирования. Запись минуя методы string посредством хаков вроде const_cast<char *>(text.data()) или &text[0] — это прямой путь в область неопределенного поведения и удивительных багов. Так что не делайте так. Выделяйте буффер (или просто массив на стеке) и копируйте через него. И используйте GetModuleFileNameW.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
_B_>Ни насколько не допустимо. К тому же, mfn.size() в данном случае 0.
не 0, а MAX_PATH (см. к-тор).
D>>По уму в строках память должна выделяться непрерывно, но вот может ли это измениться?
_B_>Это тебе кажется, что "по уму", а мне кажется, что есть стандарт языка, и в нём непрерывность гарантируется только для std::vector (и для std::string::c_str(), но этот метод возвращает константный указатель, который теоретически не обязан совпадать с собственно внутренним буфером строки).
В '03 не не обязана выделяться непрерывно, а в '11 должна.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, VTT,
VTT>Дело в том, что непрерывность массива символов гарантирована только для указателей, возвращаемых при вызове data() и c_str(), но при этом сами массивы доступны только для чтения.
Начиная с C++11 непрерывность массива символов гарантируется (21.4.1/5).
VTT>И используйте GetModuleFileNameW.
Здравствуйте, Vlad_SP, Вы писали:
V_S>Начиная с C++11 непрерывность массива символов гарантируется (21.4.1/5).
Начиная с C++11 c его move семантикой и умными указателями фокусы с copy on write и совместным владением буфферами по идее больше не нужны, так что они могли бы сделать и не const data() и давать писать в буфер строки напрямую.
V_S>С какой это стати??
т.е. как с какой? не каждый путь в ANSI строчке может быть представлен
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Здравствуйте, Vamp, Вы писали:
V>В результате имеем лишнее копирование. В С++11 я бы копировал напрямую в string.
Согласен. Но тут еще одна подоплека: разумеется потом выполняем resize() по фактическому размеру строки, а потом желательно бы и shrink_to_fit(), чтобы не таскать с собой излишний буфер. И вот как будет себя вести shrink_to_fit() прямо не известно. Да и как-то кажется мне это дурным тоном, хотя...
Здравствуйте, dosik, Вы писали:
D>Согласен. Но тут еще одна подоплека: разумеется потом выполняем resize() по фактическому размеру строки, а потом желательно бы и shrink_to_fit(), чтобы не таскать с собой излишний буфер. И вот как будет себя вести shrink_to_fit() прямо не известно. Да и как-то кажется мне это дурным тоном, хотя...
Можно сначала узнать требуемый размер строки от GetModuleFileName и выделить память сразу под него.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Здравствуйте, VTT, Вы писали:
VTT>Можно сначала узнать требуемый размер строки от GetModuleFileName и выделить память сразу под него.
Да вот в том то и дело, что не умеет он говорить сколько нужно... Он возвращает только столько, сколько влезло в буфер, а если буфера не хватило, то в GetLastError помещает ERROR_INSUFFICIENT_BUFFER.
Здравствуйте, Vlad_SP, Вы писали:
V_S>Здравствуйте, VTT, Вы писали:
VTT>>т.е. как с какой? не каждый путь в ANSI строчке может быть представлен
V_S>Да-да-да. И будем уникодные символы запихивать в std::string?
std::string — это std::basic_string< char >, но существует и std::basic_string< wchar_t >.
D> buff = std::unique_ptr<char[]>(new char[size]); //Происходит ли удаление старого буфера тут?
Да.
D> string path(std::move(&buff[0])); //Действительно ли это будет оптимальней, нежели string path(&buff[0])
Оптимальней не будет, лучше выбрать вариант без std::move.
У фундаментальных типов (у указателя в данном случае) вообще нет перемещающих конструкторов — всё делается через копирование. Ну и смысла в существовании перегрузки конструктора string, принимающего r-value ссылку на указатель, тоже нет никакого по этим причинам. Так что стоит предпочесть более короткий и понятный код.