Исчезающая строка в пользовательском классе исключений c ++ - PullRequest
1 голос
/ 22 ноября 2011

Я написал собственный класс исключений для обработки ошибок автоматизации OLE.Метод what () выглядит следующим образом:

const char* OleException::what() const throw() {
    std::string res = std::runtime_error::what();
    LPTSTR errorText = NULL;
    FormatMessage(
        FORMAT_MESSAGE_FROM_SYSTEM
        | FORMAT_MESSAGE_ALLOCATE_BUFFER
        | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        hresult,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&errorText,
        0,
        NULL);
    if(NULL != errorText) {
        res = res + " - " + errorText;
        LocalFree(errorText);
    }
    //std::cout << res << std::endl;
    return res.c_str();
}

Однако, когда я пытаюсь напечатать строку, она возвращается в моей функции main (), все, что я получаю, это буква «I».Странная часть: когда я раскомментирую вторую строку метода, он работает просто отлично, т.е. я получаю одно и то же сообщение дважды на своем терминале.Что я делаю не так?

Ответы [ 3 ]

3 голосов
/ 22 ноября 2011

Ваша проблема автоматическое уничтожение объектов, выходящих за рамки .

Ваш std :: string res является локальным для метода what (), и вы возвращаете указатель на его внутренние компоненты. Когда вы выходите из функции, локальный объект разрушается, и вы пытаетесь использовать теперь висящий указатель.

Когда вы выводите его изнутри метода what (), проблем не возникает, поскольку вы отображаете строку до ее уничтожения.

Хорошим решением вашей проблемы было бы сделать std :: string res членом данных вашего класса исключений. Тогда, пока ваш экземпляр исключения не будет уничтожен, вы можете безопасно получить доступ к содержимому строки.

1 голос
/ 22 ноября 2011

Как уже указывали другие, указатель, возвращаемый c_str, становится недействительным в момент возврата what, поскольку ret больше не существует.

Решение состоит в том, чтобы сделать сообщение об ошибкечлен вашего класса исключений типа std::string и выполняйте форматирование во время построения, а не в what.Затем вы можете безопасно вернуться из c_str.

class OleException : std::runtime_error  // just guessing here
{
    std::string msg;

  public:
    OleException()
    {
        // construct msg
    }
    const char* OleException::what() const throw() { return msg.c_str(); }
    // etc.
};
1 голос
/ 22 ноября 2011

Это очень распространенная ошибка: вы возвращаете указатель на данные, созданные локальным объектом, которые уничтожаются при выходе из функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...