Переменная C ++ больше не существует - PullRequest
1 голос
/ 14 апреля 2011
#include <exception>
#include <iostream>
#include <cstdio>

using namespace std;

class BaseException : exception {
public:
    BaseException(const char* message) : message(message) {}
    const char* getMessage() {
        return message;
    }
private:
    const char* message;
};

void wrong() {
    unsigned short int argumentCallCounter = 1;

    /// @todo check why commented below does not work ?!
    // char tmp[13 + sizeof(argumentCallCounter)];

    /// @todo but this works
    char* tmp = new char[13 + sizeof(argumentCallCounter)];
    sprintf(tmp, "No %u argument", argumentCallCounter);

    throw BaseException(tmp);
}

int main(int argc, char** argv) {
    try {
        wrong();
    } catch (BaseException e) {
        cout << e.getMessage() << endl;
    }

    return 0;
}

Код выше работает, но в комментариях есть сегмент кода, который не работает.char tmp[13 + sizeof(argumentCallCounter)];Я понимаю, что это не работает, потому что когда программа покидает функцию wrong, переменная tmp больше не существует.Кто-нибудь может помочь с этим?

А также то решение, которое я пишу:char* tmp = new char[13 + sizeof(argumentCallCounter)];Это тоже не хорошо, потому что, когда программа завершена, происходит утечка памяти, потому что никто не удаляет tmp

Ответы [ 4 ]

4 голосов
/ 14 апреля 2011

Обычно я генерирую исключение std :: runtime_exception, инициализированное с помощью std :: string.

3 голосов
/ 14 апреля 2011

http://www.cplusplus.com/reference/iostream/stringstream/ http://www.cplusplus.com/reference/std/stdexcept/runtime_error/

void wrong() {
    unsigned short int argumentCallCounter = 1;

    std::stringstream ss;
    ss << "No " << argumentCallCounter << " argument";

    throw std::runtime_error(ss.str());
}
2 голосов
/ 14 апреля 2011
//why commented below is not works
char tmp[13 + sizeof(argumentCallCounter)];

Это не будет работать, потому что tmp является локальным для функции и больше не существует после выхода из функции, но вы все еще пытаетесь получить к нему доступ из main().

Я бы предложил вам использовать std::string в BaseException и везде.

Я бы также предложил вам отловить исключение по ссылке const как:

catch (const BaseException & e)
//     ^^^^^ note          ^ note

РЕДАКТИРОВАТЬ:

Реализуйте BaseException следующим образом:

class BaseException : std::exception 
{
public:
    BaseException(std::string msg) : message(msg) {}

    //override std::exception::what() virtual function
    virtual const char* what() const throw()
    {
        return message.c_str();
    }

private:
    std::string message;
};

Используйте его как:

 try
 { 
    //some code that might throw BaseException
 }
 catch (const BaseException & e)
 {
       cout << "exception message : " << e.what() << endl;
 }

РЕДАКТИРОВАТЬ:

И реализуйтеwrong() как

void wrong() {
    unsigned short int argumentCallCounter = 1;

    std::stringstream ss;
    ss << "No " << argumentCallCounter << " argument";

    throw BaseException(tmp.str());
}
0 голосов
/ 14 апреля 2011

Что вы подразумеваете под «не работает»?

BaseException должен скопировать строку, полученную из конструктора, и сделать ее локальную копию. Затем функция wrong может освободить ее в любом случае.

И когда вы это сделаете, локальный массив tmp должен снова работать.

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