I have a simple Image cache class in my MFC application, to keep track of images loaded from the file system:
typedef boost::shared_ptr<Gdiplus::Image> ImagePtr;
typedef std::map<std::string, ImagePtr> ImageMap;
Whenever an image is requested by file name, a look up is done, or if it is already loaded, the appropriate ImagePtr is returned.
The problem occurs when I exit my application, and the shared pointer gets destructed. I get an access violation here, in checked_delete.hpp:
// 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; // <-------- violation here!!
}
Is GDI+ managing these objects for me? If so, what do I need to do to my shared_ptr so that it doesn't call delete? Or is something else awry?
Thanks in advance!
That might be a symptom of calling GdiplusShutdown before the pointers are destroyed.
Related
Consider an operation with a standard asynchronous interface:
std::future<void> op();
Internally, op needs to perform a (variable) number of asynchronous operations to complete; the number of these operations is finite but unbounded, and depends on the results of the previous asynchronous operations.
Here's a (bad) attempt:
/* An object of this class will store the shared execution state in the members;
* the asynchronous op is its member. */
class shared
{
private:
// shared state
private:
// Actually does some operation (asynchronously).
void do_op()
{
...
// Might need to launch more ops.
if(...)
launch_next_ops();
}
public:
// Launches next ops
void launch_next_ops()
{
...
std::async(&shared::do_op, this);
}
}
std::future<void> op()
{
shared s;
s.launch_next_ops();
// Return some future of s used for the entire operation.
...
// s destructed - delayed BOOM!
};
The problem, of course, is that s goes out of scope, so later methods will not work.
To amend this, here are the changes:
class shared : public std::enable_shared_from_this<shared>
{
private:
/* The member now takes a shared pointer to itself; hopefully
* this will keep it alive. */
void do_op(std::shared_ptr<shared> p); // [*]
void launch_next_ops()
{
...
std::async(&shared::do_op, this, shared_from_this());
}
}
std::future<void> op()
{
std::shared_ptr<shared> s{new shared{}};
s->launch_next_ops();
...
};
(Asides from the weirdness of an object calling its method with a shared pointer to itself, )the problem is with the line marked [*]. The compiler (correctly) warns that it's an unused variable.
Of course, it's possible to fool it somehow, but is this an indication of a fundamental problem? Is there any chance the compiler will optimize away the argument and leave the method with a dead object? Is there a better alternative to this entire scheme? I don't find the resulting code the most intuitive.
No, the compiler will not optimize away the argument. Indeed, that's irrelevant as the lifetime extension comes from shared_from_this() being bound by decay-copy ([thread.decaycopy]) into the result of the call to std::async ([futures.async]/3).
If you want to avoid the warning of an unused argument, just leave it unnamed; compilers that warn on unused arguments will not warn on unused unnamed arguments.
An alternative is to make do_op static, meaning that you have to use its shared_ptr argument; this also addresses the duplication between this and shared_from_this. Since this is fairly cumbersome, you might want to use a lambda to convert shared_from_this to a this pointer:
std::async([](std::shared_ptr<shared> const& self){ self->do_op(); }, shared_from_this());
If you can use C++14 init-captures this becomes even simpler:
std::async([self = shared_from_this()]{ self->do_op(); });
why in D I can't send to another thread through Tid.send local instances of structs?
I would like to make simple handling of thread communication like this:
void main()
{
...
tid.send(Command.LOGIN, [ Variant("user"), Variant("hello1234") ] );
...
}
void thread()
{
...
receive(
(Command cmd, Variant[] args) { ... })
)
...
}
If I understand it correctly, D should create the array of Variants in the stack and
then copy content of the array the send function right? So there should not be any
issues about synchronization and concurrency. I'm quiet confused, this concurrency is
wierd, I'm used to code with threads in C# and C.
Also I'm confused about the shared keyword, and creating shared classes.
Usualy when I try to call method of shared class instance from non-shared object, the
compiler throws an error. Why?
you should idup the array and it will be able to go through, normal arrays are default sharable (as they have a shared mutable indirection)
as is the compiler can rewrite the sending as
Variant[] variants = [ Variant("user"), Variant("hello1234") ] ;
tid.send(Command.LOGIN, variants);
and Variant[] fails the hasUnsharedAlias test
you can fix this by making the array shared or immutable (and receiving the appropriate one on the other side)
A logging structure that depends on logging related functions looks like this:
typedef struct
{
TFkt_vlogf vlogf;
TFkt_outf outf;
void* logData;
} TLogger;
In this logging function there is an abstract logData that is assigned with different pointers depending on the job that the logger has.
A Filelogger would at one point access a stored filehandle like this.
FILE * fileHandle = (FILE *)(logger->logData);
Although this compiles SPLint is unhappy about this and complains with this message:
Cast to underlying abstract type FILE *: (FILE *)(logger->logData)
What can i do to satisfy SPLint?
i tried to sprinkle some /*#abstract#*/ around but it did not help
Is there a better way in C90 to store and access data while still keeping the structure signature to pass the type around independent of its implementation?
The better Solution is to use a union and have all possible Data inside that union.
typedef union
{
FILE * fileHandle;
char something;
long int other;
} TLog_data;
typedef struct
{
TFkt_vlogf vlogf;
TFkt_outf outf;
TLog_data logData;
} TLogger;
At some point during execution you would use:
((TLogger*) logger)->logData.fileHandle
I am just trying to compile a bit bigger project using the Visual Studio 2012 Release Candidate, C++. The project was/is compiled using the VS2010 now. (I am just greedy to get the C++11 things, so I tried. :)
Apart of things that I can explain by myself, the project uses the code like this:
ostringstream ostr;
ostr << "The " __FUNCTION__ "() failed to malloc(" << i << ").";
throw bad_alloc(ostr.str().c_str());
The compiler now complains
error C2248: 'std::bad_alloc::bad_alloc' : cannot access private member declared
in class 'std::bad_alloc'
... which is true. That version of constructor is now private.
What was the reason to make that version of constructor private? Is it recommended by C++11 standard not to use that constructor with the argument?
(I can imagine that if allocation failed, it may cause more problems to try to construct anything new. However, it is only my guess.)
Thanks,
Petr
The C++11 Standard defines bad_alloc as such (18.6.2.1):
class bad_alloc : public exception {
public:
bad_alloc() noexcept;
bad_alloc(const bad_alloc&) noexcept;
bad_alloc& operator=(const bad_alloc&) noexcept;
virtual const char* what() const noexcept;
};
With no constructor that takes a string. A vendor providing such a constructor would make the code using it not portable, as other vendors are not obliged to provide it.
The C++03 standard defines a similar set of constructors, so VS didn't follow this part of the standard even before C++11. MS does try to make VS as standard compliant as possible, so they've probably just used the occasion (new VS, new standard) to fix an incompatibility.
Edit: Now that I've seen VS2012's code, it is also clear why the mentioned constructor is left private, instead of being completely removed: there seems to be only one use of that constructor, in the bad_array_new_length class. So bad_array_new_length is declared a friend in bad_alloc, and can therefore use that private constructor. This dependency could have been avoided if bad_array_new_length just stored the message in the pointer used by what(), but it's not a lot of code anyway.
If you are accustomed to passing a message when you throw a std::bad_alloc, a suitable technique is to define an internal class that derives from std::bad_alloc, and override ‘what’ to supply the appropriate message.
You can make the class public and call the assignment constructor directly, or make a helper function, such as throw_bad_alloc, which takes the parameters (and additional scalar information) and stores them in the internal class.
The message is not formatted until ‘what’ is called. In this way, stack unwinding may have freed some memory so the message can be formatted with the actual reason (memory exhaustion, bad request size, heap corruption, etc.) at the catch site. If formatting fails, simply assign and return a static message.
Trimmed example:
(Tip: The copy constructor can just assign _Message to nullptr, rather than copy the message since the message is formatted on demand. The move constructor, of course can just confiscate it :-).
class internal_bad_alloc: public std::bad_alloc
{
public:
// Default, copy and move constructors....
// Assignment constructor...
explicit internal_bad_alloc(int errno, size_t size, etc...) noexcept:
std::bad_alloc()
{
// Assign data members...
}
virtual ~internal_bad_alloc(void) noexcept
{
// Free _Message data member (if allocated).
}
// Override to format and return the reason:
virtual const char* what(void) const noexcept
{
if (_Message == nullptr)
{
// Format and assign _Message. Assign the default if the
// format fails...
}
return _Message;
}
private:
// Additional scalar data (error code, size, etc.) pass into the
// constructor and used when the message is formatted by 'what'...
mutable char* _Message;
static char _Default[];
}
};
//
// Throw helper(s)...
//
extern void throw_bad_alloc(int errno, size_t size, etc...)
{
throw internal_bad_alloc(errno, size, etc...);
}
VERSION 1
class Doh {
private:
static std::map<const std::string, const Doh*> someMap;
std::string stringValue_;
public:
Doh(std::string str) : stringValue_(str) {
Doh::someMap.insert(
std::make_pair<const std::string,const Doh*>
(this->stringValue_,this)
);
}
}
The above was ok with MSVC 2010 but with MSVC 2008 it fails – and I guess it is because the object is not constructed yet when it is inserted in the map (I got a memory access violation).
So, I tried a delayed insertion, which worked:
VERSION 2
Doh(std::string str) : stringValue_(str) {
boost::thread(&Doh::insertIntoTheStaticMap,this);
}
void insertIntoTheStaticMap() {
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
Doh::someMap.insert(
std::make_pair<const std::string,const Doh*>
(this->stringValue_,this)
);
}
But as you might be able to guess, my intention is to have the static Doh::someMap as a common lookup dictionary.
VERSION 1 didn’t need any thread-safety because I would create all Doh instances in the same thread – in initialization blocks - which would be called by dynamic initializers before I enter main().
But with VERSION 2, the naïve sleep() is neither graceful nor reliable (not to mention, I might need to lock the map before insertion).
What would be a nice KISS approach?
Only potential issue I see is the initialization of the static member, if there are multiple source files. Try guarding it with a function.
class Doh {
private:
static std::map< std::string, Doh * > &get_map() {
static std::map< std::string, Doh * > someMap;
return someMap; // initialize upon first use
}
std::string stringValue_;
public:
Doh(std::string str) : stringValue_(str) {
get_map().insert(
std::make_pair
(this->stringValue_,this)
);
}
};
In neither version is there any sign of init for stringvalue_ - what does the debugger show you about this key when you hit the map insert in version 1 of the code? How is this field set up, and what is its type?
Running this in the debugger for VS2008 should allow you to narrow down the point of failure into the <map> source, I would have thought.