Technical issue with exceptions -- throwing a char const *

Hi,

This problem is blowing my mind. I can't figure out what I'm possibly doing wrong.

Here's the code (version One):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Diminisher::loadResources()
{
    char const * filename = "player.png";
    SDL_Surface * surface = loadSurface(filename);

    if(!surface)
    {   
        char errorMessage [100];
        memset(errorMessage, 0, sizeof(errorMessage) );
        strncat(errorMessage, "Error: file not found -- ", 25);
        strncat(errorMessage, filename, strlen(filename) );
        char const * err = errorMessage;
        throw err;
    }   

    loadedSurfaces.push_back(surface);

    player = Player(surface);
    playerVelocity = 5;
}


Here's the debug output (Version One):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
josh@josh-Dell-XPS420:~/Desktop/Diminisher/Version 1$ gdb a.out
(gdb) break Diminisher::loadResources()
Breakpoint 1 at 0x804997f: file Diminisher.cpp, line 4.
(gdb) run
Starting program: /home/josh/Desktop/Diminisher/Version 1/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".

Breakpoint 1, Diminisher::loadResources (this=0xbffff2a8) at Diminisher.cpp:4
4	{
(gdb) n
5		char const * filename = "player.png";
(gdb) 
6		SDL_Surface * surface = loadSurface(filename);
(gdb) 
8		if(!surface)
(gdb) 
11			memset(errorMessage, 0, sizeof(errorMessage) );
(gdb) 
12			strncat(errorMessage, "Error: file not found -- ", 25);
(gdb) 
13			strncat(errorMessage, filename, strlen(filename) );
(gdb) 
14			char const * err = errorMessage;
(gdb) print err
$1 = 0xb7fec28b "\203\354\024\211\306e\241\f"
(gdb) print errorMessage
$2 = "Error: file not found -- player.png", '\000' <repeats 64 times>
(gdb) n
15			throw err;
(gdb) print err
$3 = 0xbffff1b8 "Error: file not found -- player.png"
(gdb) n
�v�그
[Inferior 1 (process 8769) exited normally]
(gdb) quit


Here's the code (Version Two)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Diminisher::loadResources()
{
    char const * filename = "player.png";
    SDL_Surface * surface = loadSurface(filename);

    if(!surface)
    {   
        char errorMessage [100];
        memset(errorMessage, 0, sizeof(errorMessage) );
        strncat(errorMessage, "Error: file not found -- ", 25);
        strncat(errorMessage, filename, strlen(filename) );
        char const * err = errorMessage;
        throw "Error: file not found -- player.png";
    }   

    loadedSurfaces.push_back(surface);

    player = Player(surface);
    playerVelocity = 5;
}


Here's the debug output (Version Two):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
josh@josh-Dell-XPS420:~/Desktop/Diminisher/Version 1$ gdb a.out
(gdb) break Diminisher::loadResources()
Breakpoint 1 at 0x804997f: file Diminisher.cpp, line 4.
(gdb) run
Starting program: /home/josh/Desktop/Diminisher/Version 1/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".

Breakpoint 1, Diminisher::loadResources (this=0xbffff2a8) at Diminisher.cpp:4
4	{
(gdb) n
5		char const * filename = "player.png";
(gdb) 
6		SDL_Surface * surface = loadSurface(filename);
(gdb) 
8		if(!surface)
(gdb) 
11			memset(errorMessage, 0, sizeof(errorMessage) );
(gdb) 
12			strncat(errorMessage, "Error: file not found -- ", 25);
(gdb) 
13			strncat(errorMessage, filename, strlen(filename) );
(gdb) 
14			char const * err = errorMessage;
(gdb) 
15			throw "Error: file not found -- player.png";
(gdb) print err
$1 = 0xbffff1b8 "Error: file not found -- player.png"
(gdb) n
Error: file not found -- player.png
[Inferior 1 (process 8793) exited normally]
(gdb) quit


A few important things to notice:
The only difference between the code is on the throw line (line 13).

The difference between these two lines and the output of the program is profound:
debug output one, line 34
debug output two, line 30

errorMessage holds the same exact message as the thrown message, but displays something different:
debug output one, line 27 & 31
debug output two, line 27

I thought it might be because of the way errorMessage is defined inside a function.. but that shouldn't matter. once it's been initialized (which it has before it's thrown) it should be able to be referenced from anywhere within the executable. The string is reserved in the program's memory.

Now I'm thinking it's because of the way errorMessage is cleared.
if you noticed, there is a subtle difference between the way err is printed and errorMessage is printed. errorMessage has a bunch of '\000' after.. but even if.. on output one line 31, it's clear that printing err (the same location as errorMessage) leaves out the \000's...

Any help?
Last edited on
You cannot access the local variable errorMessage outside its function. It's just invalid. You need to new the memory for the message you want to throw.

I'd avoid exceptions. If you really want to better use std::exception:

http://www.cplusplus.com/reference/std/exception/exception/
Thankyou coder777, you are right.
I moved errorMessage to being declared inside the object and now all is well.

I have to admit, it strikes me as a bit peculiar though that errorMessage can't be accessed from outside the function. c++ must reuse the memory for something? I don't know...

I know using char const * isn't the usual way to do things, but I didn't see any reason to use exception, especially sense the thrown exceptions never leave the class.

Are there good reasons to use std::exception over char const * except for conforming to the standard way of doing things?
closed account (zb0S216C)
SexyBachelor wrote:
"Are there good reasons to use std::exception over char const * except for conforming to the standard way of doing things?"

The std::exception method is more maintainable.

Try using structures:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <exception>

struct MyCustomException : public std::exception
{
    const char *what() const
    {
        return("My Exception Was Thrown");
    }
};

void ThrowException()
{
    throw(MyCustomException());
}

int main()
{
    try { ThrowException(); }
    catch(MyCustomException &Caught)
    {
        std::cout << Caught.what();
    }
}

Wazzak
Last edited on
Topic archived. No new replies allowed.