A Memory allocation question in exceptions.

1
2
3
4
5
6
7
8
9
10
11
12
try
{
  void someFunction()
  {
    ....
    throw "Exception";
  }
  catch (char* exc)
  {
    ...
  }
}


Above, a string will be created and thrown, Is the string allocated in heap or stack? Will it be in-scope within the catch clause?
Last edited on
it is "string literal" and is in static data segment which is part of stack.
Sure, it will be in-scope within the catch clause?
However, it is not recommended, because catching an exception by a pointer is very dangerous in the following aspects
1. you don't know how to deal with the ownership of this pointer.
2. when dealing with pointers, you alway need to check the validity, namely if(!p), what a waste!
3. return a pointer to a local variable is one famous source of "undefined behavior".
4. many other issues....

so the correct way is to catch an exception by reference.
for your special case, the compiler will let it go and there is no run time error. but certainly not recommended.
Last edited on
everid wrote:
it is "string literal" and is in static data segment which is part of stack.

I think you will find that the static data segment is not part of the stack.

http://en.wikipedia.org/wiki/Data_segment

The literal string "Exception" will likely be stored in the data segment. When the exception is thrown it is only the address of the string that is being thrown which I think will be created on the stack-frame of the catch block.

And this will not compile...
1
2
3
4
5
6
7
8
9
10
11
12
try
{
  void someFunction()
  {
    ....
    throw "Exception";
  }
  catch (char* exc)
  {
    ...
  }
}


I think you meant something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

void someFunction()
{
	//...
	throw "Exception";
}

int main()
{
	try
	{
		someFunction();
	}
	catch(const char* msg)
	{
		std::cout << msg << std::endl;
	}

	return 0;
}
I think you will find that the static data segment is not part of the stack.

oops, thanks, this corrects my misunderstandings for years. although this misunderstanding never gave me any real bugs, because i can distinguish local and static.
thanks.
Last edited on
btw, op's code will compile but most likely gives a warning sign.
"string literal" can be deprecated and converted to a non-const pointer.
try to modify "string literal" by using a non-const pointer at run time is undefined.
Last edited on
Which is why the string isn't in any data segment either; the pointer yes, the actual
characters of the string no... they are somewhere with the executable code in a read-only
page.
C++ Gotchas devotes an entire item to never throwing string literals as exceptions.

Consider:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
try
{
    //...
    throw "this";
    //...
    throw "that";
    //...
}
catch( const char * e )
{
    std::string s( e );
    if( s == "this" )
    {
        // handle this exception
    }    
    if( s == "this" )
    {
        // handle that exception
    }
    else
    {
        // now what?  rethrow?
    }
}


Basically, the exception doesn't carry any information about what happened. The catch statement cannot differentiate between different exceptions so the catch block must then examine its value before handling it.

Compare that to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct This : public std::exception {};
struct That : public std::exception {};
//...
try
{
    //...
    throw This();
    //...
    throw That();
    //...
}
catch( This & e )
{
    // handle this exception
}
catch( That & e )
{
    // handle that exception
}
catch( ... )
{
    // now what?  rethrow?
}


Now, a new exception could be added with less changes to unrelated catch blocks, the exception classes could easily be extended to carry more information, and their handling is [arguably] more readable.
Last edited on
1
2
3
4
5
6
7
            if(ucode==ERROR_DRIVER_BLOCKED)
            {
                LogString(L"Driver successfully blocked");	//driver was blocked => test passes
                bTestPass=TRUE;
            }
            else
                throw DriverNotBlocked;


Above code gives compilation error: error C2275: 'DriverNotBlocked' : illegal use of this type as an expression

Here's how DriverNotBlocked class is defined:
1
2
3
4
5
6
7
8
class DriverNotBlocked:public std::exception
{
public:
	virtual const char* what() throw()
	{
		return "DriverNotBlocked";
	}
};


There are similar other Exception classes declared, that works just fine. It seems to have a problem with just this class. Can we really throw exceptions from else blocks? Or any other ideas?
Never mind, found it. I had to return an object, not the class :)

Thanks!
Try:
throw DriverNotBlocked();

EDIT: Yep, you got it.
Last edited on
Topic archived. No new replies allowed.