0

I need help to understand what I'm doing wrong in the following Initialization List. I'm using it to initialize a data member object "RoomResources" that doesn't have a default constructor in my "Room" class:

/* Public methods */
public:

//Constructor - Initialization list with all data member objects that doesn't have a default constructor
Room(const AppDependencies* MainDependencies, RoomId room_id, int width, int height, int disp_width, int disp_height) :

    RoomResources(this->GetAppRenderer())

    {
        //Store the provided initialization data
        this->MainDependencies = MainDependencies;
        this->room_id = room_id;
        this->width = width;
        this->height = height;
        this->disp_width = disp_width;
        this->disp_height = disp_height;

        //Set instance count
        this->instance_count = 0;

        //Load corresponding room resources
        this->Load(room_id);
    }

Now this compiles correctly, and seems ok to me, but it is causing a crash when I start my program. I know this Init List is the problem because I tried not using it and having a "RoomResources" object instead with a default constructor and my program is running fine.

When I debug my program I get the following error: "Can't find a source file at "e:\p\giaw\src\pkg\mingwrt-4.0.3-1-mingw32-src\bld/../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/main.c""

It seems like some object is trying to call some code or data that isn't available yet in the program but I can't see the problem in my code. Thanks very much for your time.

EDIT: Here is the definition of my GetAppRenderer method:

const SDL_Renderer* Room::GetAppRenderer() {

//Return the const pointer to the App's SDL_Renderer object found in the AppDependencies data member
return this->MainDependencies->MainRenderer;
}
7
  • Is GetAppRenderer() virtual? Also why are you using the init list for only the first thing (RoomResources)? Commented Jul 20, 2014 at 14:16
  • No GetAppRenderer() simply returns the pointer that can be found in MainDependencies. Commented Jul 20, 2014 at 14:18
  • I'm using it only for RoomResources because it's the only data member object that doesn't have a default empty constructor. Commented Jul 20, 2014 at 14:19
  • 3
    Well there's your problem, this->MainDependencies = MainDependencies; hasn't been executed. Its pointing to garbage data when you call GetAppRenderer() Commented Jul 20, 2014 at 14:19
  • 1
    The point of the init list is it gets executed before the body of the constructor. At which point all your members have been default initialized and you're basically doing it a second time in the body. Commented Jul 20, 2014 at 14:23

1 Answer 1

3

Your problem is MainDependencies hasn't been initialized yet (because the initialization list is executed before the body of the main constructor) so when you call GetAppRenderer(), MainDependencies is still pointing to garbage data and you get a crash.

You can solve your problem this way:

Room(const AppDependencies* MainDependencies, RoomId room_id, int width, int height, int disp_width, int disp_height) :
    // Order is important (GetAppRenderer needs MainDependencies to be initialized)
    MainDependencies(MainDependencies), RoomResources(this->GetAppRenderer())

    {
        //Store the provided initialization data
        this->room_id = room_id;
        this->width = width;
        this->height = height;
        this->disp_width = disp_width;
        this->disp_height = disp_height;

        //Set instance count
        this->instance_count = 0;

        //Load corresponding room resources
        this->Load(room_id);
    }

P.S: I would use the init list for all the other member variables

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks very much this is indeed the problem. How can I initialize a contained object without a default constructor after the owner has been initialized? Do I absolutely have to create a method and call it explicitly to do it once the object is created?
@MajorScientist Well in your case I've solved it by initializing MainDependencies in the init list before RoomResources. In the general case its hard to say.
Ok you edited the answer with a solution. Thank you very much, I understand the Initialization List much better now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.