Почему функция не возвращает строку?
char* take_module_name()
{
TCHAR FilePath[MAX_PATH + 1]; // буфер для имени файла
GetModuleFileName(NULL, FilePath, sizeof(FilePath) / sizeof(FilePath[0]));
int lastSlash = 0;
for (int i = 0; i < MAX_PATH + 1; i++)
{
if (FilePath[i] == '\\' || FilePath[i] == '/')lastSlash = i;
}
char filename[40];
strcpy(filename, &FilePath[lastSlash + 1]);
filename[39] = '\0';
return filename;
}
Почему когда я вызываю эту функцию она не выводит имя файла, хотя filename в функции выводится нормально? Вызываю так:
cout << take_module_name();
Хотя если так делать то все работает, но через раз:
string file_way = (string)OBF("DEL /q %systemroot%\\Prefetch\\") + take_module_name();
cout << file_way;
P.s как оказалось цикл иногда возвращает неправильный lastSlash ,но почему ,для меня непонятно.
Ответы (3 шт):
изменяем
stringпереданный по ссылкеvoid foo(std::string& message) { message = "hello"; }возвращаем
stringstd::string foo() { std::string message = "hello"; return message; }изменяем массив char переданный в функцию
void foo(char* message) { strcpy_s(message, 6, "hello"); }возвращаем указатель на динамический массив char выделенный в функции, но это очень плохой вариант, так как нужно чтобы кто-то снаружи зачистил память
char* foo() { char* message = new char[6]; strcpy_s(message, 6, "hello"); return message; }
также рекомендую использовать функцию strcpy_s вместо strcpy так как c помощью неё вы будете уверены сколько символов вы записываете в целевую строку и избежите переполнения буфера если строка-источник длинней результирующей строки
О возврате указателя на локальную переменную уже написал @Ildar. Но в коде есть ещё одна ошибка - в следующем коде
for (int i = 0; i < MAX_PATH + 1; i++)
{
if (FilePath[i] == '\\' || FilePath[i] == '/')lastSlash = i;
}
Дело в том, что строка FilePath может быть короткой, а в конце массива будет мусор. и там вполне могут быть символы слеша. Как исправить? Можно подсунуть правильную длину вместо MAX_PATH+1, но я так понимаю, это не интересно.
Можно так
for (int i = 0; i < MAX_PATH + 1; i++)
{
if (FilePath[i] == '\\' || FilePath[i] == '/')lastSlash = i;
if (FilePath[i] == 0) break; // достигли нулевого символа - выходим.
}
А можно просто занулить весь массив изначально.
К ответу KoVadim, хотел бы добавить, что у вас есть ошибка при передаче аргументов в функцию strcpy, вторым аргументом которого должен быть const char*, а вы передаете TCHAR*. Я бы предложил:
const std::string take_module_name()
{
TCHAR FilePath[MAX_PATH + 1];
GetModuleFileName(NULL, FilePath, MAX_PATH);
int lastSlash = 0;
for (int i = 0; FilePath[i] != L'\0'; i++)
{
if (FilePath[i] == '\\' || FilePath[i] == '/')lastSlash = i;
}
return std::string( (char*)&FilePath[lastSlash + 1]);
}