Добавление указателя на строку в C++
Вопрос
Меня смущают константные указатели в C++, и я написал небольшое приложение, чтобы посмотреть, каким будет результат.Я пытаюсь (я полагаю) добавить указатель на строку, которая не должна работать правильно, но когда я запускаю программу, я правильно получаю «привет, мир».Может ли кто-нибудь помочь мне понять, как работает эта строка (s += s2)?
Мой код:
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
const char* append(const char* s1, const char* s2){
std::string s(s1); //this will copy the characters in s1
s += s2; //add s and s2, store the result in s (shouldn't work?)
return s.c_str(); //return result to be printed
}
int main() {
const char* total = append("hello", "world");
printf("%s", total);
return 0;
}
Решение
Переменная s
является локальным внутри append
функция.Однажды append
Функция возвращает, что переменная уничтожена, оставляя указатель на строку, которая больше не существует.Использование этого указателя приводит к неопределенное поведение.
Мой вам совет, как решить эту проблему:Использовать std::string
весь путь!
Другие советы
ты добавляешь const char*
указатель на std::string
и это возможно (см. эта ссылка).невозможно было бы выполнить эту операцию на char*
тип (строка в стиле C).
однако вы возвращаете указатель на локальную переменную, поэтому как только функция append
возвращается и извлекается из стека, строка, на которую указывает возвращенный указатель, не будет существовать.это приводит к неопределенному поведению.
Класс std::string перегружен operator +=
для операнда типа const char *
basic_string& operator+=(const charT* s);
Фактически он просто добавляет строку, на которую указывает этот указатель, к содержимому объекта типа std::string, выделяя дополнительно память, если это необходимо.Например, внутри перегруженный оператор может использовать стандартную функцию C. strcat
Концептуально это похоже на следующий фрагмент кода.
char s[12] = "Hello ";
const char *s2 = "World";
std::strcat( s, s2 );
Учтите, что ваша программа имеет неопределенное поведение, потому что total
будет недействителен после уничтожения локальных объектов после выхода из функции добавления.Итак, следующее утверждение в main
printf("%s", total);
может привести к неопределенному поведению.