开发者

C++ variable no longer exists

#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;
}

The code above works, but in comments, there is a code segment, that does not work.

char tmp[13 + sizeof(argumentCallCounter)];

I understand that it does not work because when the program leaves function wrong the variable tmp no longer exists.

Can anybody help with this?

And also that decision that I write:

char* tmp = new char[13 + sizeof(argumentCallCounter)];

It's no good either, becaus开发者_如何学运维e when the program is complete, there is a memory leak, because nobody deletes tmp


I am usually throwing a std::runtime_exception initialized with a std::string.


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());
}


//why commented below is not works
char tmp[13 + sizeof(argumentCallCounter)];

It would not work because tmp is local to the function, and it not more exists once you exit from the function, but you're still trying to access it from main().

I would suggest you to use std::string in BaseException and everywhere else.

I would also suggest you to catch the exception by const reference as:

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

EDIT:

Implement BaseException as follows:

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;
};

Use it as:

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

EDIT:

And implement wrong() as

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

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

    throw BaseException(tmp.str());
}


What do you mean by “not works”?

The BaseException should copy the string it gets from the constructor, and make a local copy of it. Then, the wrong function can deallocate it in any case.

And when you do that, the local tmp array should work again.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜