Where does exception object have its space, heap or stack, and how to access it in different class?
Asked Answered
N

4

8

Recently an interviewer asked me where the exception object in C++ is allocated, heap or stack? I'm not sure but I answered stack since I thought there is no "new" or "malloc". Is it correct?

Then he kept asking me that if it's on stack, assuming class A throw a exception object, let's say "e", and class B catch "e". Since "e" is on the stack of A, then how does B can have the access to this "e"?

I'm not very clear about the second question. Could anyone can give me some example code showing that "class A throw e and class B catch it"? Also, I guessed B can catch e by copying the value or address but the interviewer only denied my answer without giving me right one, so what is the right answer, is there any mechanism can ensure class object can catch exceptions from other class objects? Thanks~

Nescience answered 2/12, 2014 at 21:49 Comment(7)
Classes with stacks of their own? That sounds like a confused interviewer. A stack is used to implement functions and the entire program uses the same one; functions throw exceptions, functions catch exceptions.Plush
@Plush - a program can have multiple stacks. It is up to the compiler and options selected. Typically, a program uses the same stack throughout its lifetime, but it is not required.Evenhanded
THe answer is neither.Vehement
@Deduplicator: Answerers seem to disagree. Care to explain?Betide
Simple, Kerrek's quote is authoritative.Vehement
#1654650Vehement
@Vehement Or both:-). It's up to the implementation. (But in practice, it is neither. It's hard to imagine an implementation which used either, and would still work.)Outvote
D
9

From [except.throw]/15.1/4:

The memory for the exception object is allocated in an unspecified way, except as noted in 3.7.4.1.

The final reference, [basic.stc.dynamic.allocation]/4, says:

[Note: In particular, a global allocation function is not called to allocate storage for [...] an exception object (15.1). — end note]

Density answered 2/12, 2014 at 22:4 Comment(4)
The note is a little ambiguous (at least without more context). Clearly, an exception can't be allocated by the usual stack allocation mechanism, so some sort of allocation function must be called. (But the key to the answer is in the first quote. Of the implementations I've actually studied, all use a custom allocation mechanism, so the exception is neither on the heap nor on the stack.)Outvote
@JamesKanze: You're right, the context (namely that this is relating to the definition of global allocation function) would have helped here.Density
Yes. I presume that it is referring to the global allocation functions described in §3.7, since these cannot be used for exceptions, at least not exclusively. But out of context, one could easily understand it to mean any allocation function which was accessible globally.Outvote
clang calls a function that allocates the exception-object and that might return nullptr if the exception-object couldn't be allocated; so this seems a usual heap-allocation. If the function returns nullptr, the code generated by clang calls std::terminate(). I think that's the usual way exception-objects are allocated.Triable
P
1

It can't be stack as the when exception is thrown stack unwinds and you'd lose the exception object if allocated in the frame that caused the exception.

I remember reading something about it in C++ Primer, 5Ed. It said

The exception object resides in space, managed by the compiler, that is guaranteed to be accessible to whatever catch is invoked. The exception object is destroyed after the exception is completely handle.

And looking at @Kerrek's asnwer above along with it, I believe it's a separate space allocated and is specific to compilers.

Putout answered 3/7, 2017 at 10:30 Comment(0)
S
0

"but I answered stack since I thought there is no "new" or "malloc". Is it correct?"

Basically yes, though exception handling is a bit special because it unwinds the stack for throw operations.

 struct SomeException {
 };

 void throwing_func() {
      throw SomeException();
 }

 int main() {
     try {
         throwing_func();
     }
     catch(const SomeException& ex) {
         std::cout << "Caught 'SomeException' exception" << std::endl;
     }
 }

The local scope of

void throwing_func() {
      throw SomeException();
}

is somehow equivalent as looking to a local scope and matching that kind of local scope with the best matching catch(...) statement.

Senter answered 2/12, 2014 at 22:7 Comment(0)
V
0

throw new std::exception vs throw std::exception

The above link has a pretty good answer.

I think the answer would be "usually" heap since you are throwing an object which would be located on the heap but if it is a static object (not sure if such a thing exists) then it would be on the stack.

Viscous answered 2/12, 2014 at 22:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.