c ++, как бороться с методом, возвращающим либо NULL, либо std :: string?

Я немного застрял с некоторым кодом. Я должен использовать тип возвращаемого значения метода getToto() который обычно возвращает std::string, но в одном случае это возвращает false (Это часть библиотеки, которую я должен использовать, я не могу ее изменить). Я понимаю, что это эквивалентно нулевому указателю. Но я не могу найти правильный способ поймать это!

test.cpp

static std::string getToto(){
char buffer[1024];
if ( CTX_Get_Env(buffer, "Toto", 1024) )
return false;
return buffer;
}

Если я попробую

const char* returned = Test::getToto().c_str();
if (returned==NULL){
std::cout<< "null pointer"<<std::endl;
}

Я получаю ошибку во время работы

прекращение вызова после создания экземпляра ‘std :: logic_error’

what (): basic_string :: _ S_construct NULL недействительно

Извините, у меня довольно низкий уровень в C ++.

1

Решение

Это зависит. Возвращает пустую строковую часть логики или это исключительное условие.

Если это не должно произойти, вы должны выдать ошибку.

Если все нормально, если строка пустая, вам следует просто вернуть пустую строку:

 return std::string();

Причина, по которой он компилируется как есть, состоит в том, что false интерпретируется как 0, который NULL, который может быть char*Таким образом, из него пытаются создать строку. Тем не менее, построение std::string из NULL указатель недействителен, поэтому вы получаете исключение.

Вот как я могу написать это:

static std::string getToto(){
char buffer[1024];
if ( CTX_Get_Env(buffer, "Toto", 1024) )
throw InvalidDataInBufferException();
return buffer;
}

если строка не должна быть пустой, или

static std::string getToto(){
char buffer[1024];
if ( CTX_Get_Env(buffer, "Toto", 1024) )
return std::string();
return buffer;
}

если это нормально для строки, чтобы быть пустым.

3

Другие решения

Неявный std::string(const char*) конструктор инициализируется с false, который интерпретируется как нулевой указатель. Построение std::string от нулевого указателя запрещено стандартом. На вашей платформе это вызывает исключение. Если вы не можете изменить функцию, вы можете поместить вызов функции в блок try, но учтите, что это ни в коем случае не гарантирует работу на других платформах.

try {
std::string returned = Test::getToto().c_str();
const char* c = returned.c_str();
} catch(...) {
// handle the error
}

Примечание 1: Поскольку реализации не обязаны вызывать исключение, если std::string инициализируется из нулевого указателя, вызывая getToto() функция может привести к неопределенному поведению. try-catch Блоки помогают только в том случае, если ваша реализация выдает исключение и поэтому не является переносимым решением. Это также означает, что функция библиотеки getToto(), вызывая неопределенное поведение, следует избегать.

Заметка 2: Исключение скрывает другую ошибку, здесь:

const char* returned = Test::getToto().c_str();

Test::getToto() возвращает временную строку, которую вы не назначаете. Ваш returned указатель остается висящим В моем примере кода я назначаю возврат std::string, затем получить указатель на свои внутренние данные char.

3

Вы должны понимать, что вы получили исключение, ДО того, как getToto () действительно вернется. Нет никакого способа сделать ‘return false’ из функции, возвращающей строку, и не получить исключение. Это просто ошибка.
Вы можете переопределить его с помощью блока try / catch следующим образом:

const char* returned = NULL;
try{
returned = Test::getToto().c_str();
}catch(std::exception& e){
std::cout << "null pointer" << std::endl;
}

но это все-таки ПЛОХАЯ вещь.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector