Jump to content
  • Advertisement
Sign in to follow this  
kerilynne

Boost causing runtime errors, I must be doing something wrong :d

This topic is 3876 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here is the boost source causing the error:
// verify that types are complete for increased safety

template<class T> inline void checked_delete(T * x)
{
    // intentionally complex - simplification causes regressions
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;
}




I'm reading the documentation on it now. Can anyone help me make sense of this?
Quote:
The header <boost/checked_delete.hpp> defines two function templates, checked_delete and checked_array_delete, and two class templates, checked_deleter and checked_array_deleter. The C++ Standard allows, in 5.3.5/5, pointers to incomplete class types to be deleted with a delete-expression. When the class has a non-trivial destructor, or a class-specific operator delete, the behavior is undefined. Some compilers issue a warning when an incomplete type is deleted, but unfortunately, not all do, and programmers sometimes ignore or disable warnings. A particularly troublesome case is when a smart pointer's destructor, such as boost::scoped_ptr<T>::~scoped_ptr, is instantiated with an incomplete type. This can often lead to silent, hard to track failures. The supplied function and class templates can be used to prevent these problems, as they require a complete type, and cause a compilation error otherwise.
I think its this one unfortunately... "A particularly troublesome case is when a smart pointer's destructor, such as boost::scoped_ptr<T>::~scoped_ptr, is instantiated with an incomplete type. This can often lead to silent, hard to track failures." This is the class I use boost in, the only class:
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H

#include <vector>
#include <map>
#include <string>
#include <boost\shared_ptr.hpp>
#include <boost\weak_ptr.hpp>
#include <iostream>

template< typename T_ >
class Resource_Manager
{  

public:

	typedef T_ value_type; // std library convention 

	typedef boost::shared_ptr<T_> Resource_Ptr;
	typedef boost::weak_ptr<T_> Resource_Observer;
	typedef std::map< std::string, Resource_Ptr > Resource_Map;
	Resource_Manager<T_>() {};
	~Resource_Manager<T_>() {};

	bool manage_resource(const std::string & name, T_ * type)
	{
		Resource_Map::iterator it = mResources.find(name);
		if (it == mResources.end())
		{
			Resource_Ptr Raw_Resource(type);
			mResources.insert(std::make_pair(name,  Raw_Resource));
			return true;
		}
		else
		{
			return false;
		}
	}

	Resource_Observer get_resource(const std::string & name)
	{
		Resource_Map::iterator  it = mResources.find(name);

		if (it == mResources.end())
		{
			std::cout << "This resource does not exist!";
		}
		else
		{
			return Resource_Observer(it->second);
		}
	}

	void remove_resource(const std::string & name)
	{
		Resource_Map::iterator it = mResources.find(name);

		if (it != mResources.end())
		{
			mResources.erase(it);
		}
	}

private:
	Resource_Map  mResources;
};

#endif

Explain me: Complete type?

Share this post


Link to post
Share on other sites
Advertisement
A complete type is one where the compiler knows exactly how large it is, and how to create/destroy it. An incomplete type is one where the compiler knows its name, and therefore allows pointers to objects of that type, but can't create or destroy them as it doesn't know its size or contents.

In this case, manage_resource takes a pointer to a 'T', and creates a scoped_ptr for it. If 'T' in this case is an incomplete type, then it won't know how to delete that T item when it needs to.

So basically, I guess you are using that resource manager on an incomplete type, eg. one you've just forward declared or something. In order for smart pointers to manage the objects of that type, they will need to know exactly what that type is.

Share this post


Link to post
Share on other sites
the only resource manager i implemented that might be of an incomplete type is this one in here:


class Settings
{
public:
Settings(){}
friend class Card_Game;

void display_options()
{
option_list.display_list();
}
void add_option(Option * option)
{
m_rOptions.manage_resource(option->name(), &(option) );
if(option->internal_setting == false)
{
option_list.add_node(option->name());
}
}
Linked_List<std::string> option_list;
Resource_Manager<Option*> m_rOptions;
};


This is the code I initialized when I got the runtime error.

Here are my Option objects:


#ifndef OPTIONS_H
#define OPTIONS_H
#include <string>
struct Option
{
friend class Settings;
private:
virtual void toggle(){}
std::string name(){return option_name;}
protected:
std::string option_name;
bool internal_setting;
Option(){}
};

////////In order from top to bottom/////////

/*
Setting for the Minimum Bet
Internal setting for house betting only
Internal setting for reloading players
Setting for betting on/off
*/


struct Minimum_Bet : public Option
{
friend class Settings;
public:
void toggle(int min_bet)
{
minimum_bet = min_bet;
}
static Minimum_Bet * Minimum_Bet::get_option()
{
return &option;
}
private:
static Minimum_Bet option;
int minimum_bet;
protected:
Minimum_Bet()
{
option_name = "Minimum Bet";
internal_setting = false;
}

};

struct All_Bets_on_House : public Option
{
friend class Settings;
public:
void toggle(bool true_false)
{
all_bets_on_house = true_false;
}
static All_Bets_on_House * All_Bets_on_House::get_option()
{
return &option;
}
private:
static All_Bets_on_House option;
bool all_bets_on_house;
protected:
All_Bets_on_House()
{
option_name = "All bets on house";
internal_setting = true;
}
};

struct Reload_Players : public Option
{
friend class Settings;
public:
void toggle(bool true_false)
{
reload_players = true_false;
}
static Reload_Players * Reload_Players::get_option()
{
return &option;
}
private:
bool reload_players;
static Reload_Players option;
protected:
Reload_Players()
{
option_name = "Reload Players";
internal_setting = true;
}

};

struct Betting : public Option
{
friend class Settings;
public:
void toggle(bool true_false)
{
betting_toggle = true_false;
}
static Betting * Betting::get_option()
{
return &option;
}
private:
bool betting_toggle;
static Betting option;
protected:
Betting()
{
option_name = "Betting On/Off";
internal_setting = false;
}
};
#endif



Is there something I'm doing wrong in the options classes to cause this runtime error to occur? Are these incomplete types?

Share this post


Link to post
Share on other sites
This line:
m_rOptions.manage_resource(option->name(), &(option) );

is bad mojo. This gives the address of a stack pointer to your manager. Which it then tries to treat as if it was dynamically allocated memory. Which means it later tries to delete a pointer on the stack.

This is actually two problems: one, you're resource manager is templated with Option * rather than just Option. This means it's trying to manage the pointers rather than the actual objects. Two, you're mixing raw pointers and smart pointers without tracking ownership properly. If you use shared_ptr, you should sink any new'd object into a shared_ptr immediately, and then use shared_ptrs to reference it. So your manage_resource function signature should look more like:

bool manage_resource(const std::string & name, Resource_Ptr type);


Also, in the future try including the actual runtime error. It's entirely possible that someone could have seen that you were trying to delete something on the stack just from the memory addresses involved.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!