   printf doesn't work anymore after some time
  Hi,I have a strange behaviour of my console application: at some time, the console window simply stops outputting the printf commands, but all the rest works, it is like the command gets ignored after some time.The console application loads several modules at the beginning, and then unloads them before ending.I could narrow down when the strange behaviour happens, and it is always in the middle of one of following two loops:(1) When loading the modules at the beginning:for (int i=0;i<int(pluginStartAddresses.size());i++){if (pluginStartAddresses(mainWindow,instanceCnt)==0){ // Here, initialization failed, we unload this module:FreeLibrary(pluginInstances);printf("Initialization failed");pluginInstances.erase(pluginInstances.begin()+i);pluginStartAddresses.erase(pluginStartAddresses.begin()+i);pluginEndAddresses.erase(pluginEndAddresses.begin()+i);i--;}}(2) When unloading the modules at the end:for (int i=0;i<int(pluginInstances.size());i++){FreeLibrary(pluginInstances);printf("Unloaded %s\n",pluginNames);}What could I possible do wrong?Don't mark threads 'solved' in this forum. -- jpetrie[Edited by - jpetrie on May 14, 2009 11:29:35 AM]
  In C++, we like to use std::cout for outputting to standard out (like the console).  cout stands for "character output" and is used to output characters to standard out (you're console is showing you the output from standard out).  A good tutorial for C++ input/output can be found here.  printf is a C function and is pretty error prone (at least for beginners), plus it lacks a lot of the functionality of the C++ std::cout.  Try to avoid using printf when writing C++.Also, what are pluginStartAddresses and pluginInstances?  They look like C++ std::vectors, but what types do the standard containers hold?  Also, is pluginStartAddresses a list of function pointers or functors?  Because when you do pluginStartAddresses(mainWindow,instanceCnt)==0 in your code, you're treating each element stored in pluginStartAddresses like a function rather than a typical object.  Without knowing more about the types of pluginStartAddresses and pluginInstances we can't really tell you exactly what is wrong.You could also be overrunning the end of the arrays/vectors/containers in your loops.  You're accessing multiple arrays/vectors/containers in the loops but you're only checking the index against one array/vector/container's size.  In your first loop you decrement i when something happens, but it's really unclear just what that is.Oh, and formatting your code with [source][/source] or [code] tags really helps the readability.  I have a hard time reading all that code when it's mushed together like that with no formatting.  The source code tags are documented here.[Edited by - MikeTacular on May 10, 2009 11:31:12 PM];  What are the plugins and what do they do? My guess is that something is redirecting stdout.   ;  Thanks for the replies!Yes I know I shouldn't be using printf, and stick to cout instead. A bad habit I should change.pluginStartAddresses is a vector containing the dll's entry function pointers (used to initialize the module). The functions return 0 if initialization failed.The plugins are extension modules that add additional functionality to the main application, but they operate well (no strange behaviour there).Actually, I rebooted the PC and since then the problem disappeared. Actually I wanted to replace printf with cout to see if that made a difference, but as it seems, it was some other strange behaviour (Windows-level?). Actually that behaviour started to happen at the same time where the console window would simply disappear from the Windows toolbar (bottom of the monitor) (but the application was still running.) But again, since I rebooted the PC, no such strange behaviour anymore.Thanks a lot and sorry for the false alarm.;  Wait wait wait wait.  This is screaming undefined behavior to me.  The problem with undefined behavior is that it's, well, undefined.  Just because it appears to be working doesn't mean that everything is good and right.  This often leads to major bugs because some use of undefined behavior somewhere in the program seems to work and be ok until something changes and then suddenly everything breaks.  It's hard to catch the real bug though because you may have written that bug somewhere deep in the code months ago and only now do you know something is wrong (though you probably have no idea what the real culprit is).Anyway, what I'm trying to say is this: just because it's working doesn't mean it's right.  You could (and probably do) have a bug somewhere that's causing undefined behavior.  It might appear to work one day, and the next day all hell will break loose.  Have you carefully stepped through it with the debugger?Oh, and nice use of the source tags! [smile]   ;Quote:Original post by MikeTacularIn C++, we like to use std::cout for outputting to standard out (like the console).  cout stands for "character output"I'm pretty sure it's "console output", actually. After all, to the extent that any output can be said to be composed of characters, it all is. :)Quote:In your first loop you decrement i when something happens, but it's really unclear just what that is.That appears to be an attempt to "redo" the current iteration. Since the current element is being erased, he doesn't want to advance the index, because that would then skip an element.Keeping three separate lists like that is messy. Trying to remove elements from a sequence that you're iterating over, manually, is also messy. (And done in the OP's way, it's inefficient if the container is a vector.) Here is a sketch of how to do this sort of thing more neatly in C++:struct Plugin {  PluginInstance instance;  PluginStartAddress start_address;  PluginEndAddress end_address;  ~Plugin() { FreeLibrary(instance); }  boolean initialize(const Window& window, int instance_count) {    return start_address(window, instance_count) != 0;  }};struct couldnt_initialize_with {  const Window* toInitializeWith;  int instance_count;  couldnt_initialize_with(const Window& window, int instance_count) : toInitializeWith(&window), instance_count(instance_count) {}  bool operator(Plugin& plugin) { return !plugin.initialize(*toInitializeWith, instance_count); }};std::vector<Plugin> plugins; // instead of the containers you currently have// remove_if comes from <algorithm>.plugins.erase(std::remove_if(plugins.begin(), plugins.end(), couldnt_initialize_with(mainWindow, instanceCnt)), plugins.end());// Yes, that replaces both loops. When the vector of Plugins falls out of scope,// the destructor is called for each Plugin, which in turn calls FreeLibrary// for each PluginInstance.;Quote:Original post by ZahlmanI'm pretty sure it's "console output", actually. After all, to the extent that any output can be said to be composed of characters, it all is. :)According to Bjarne Stroustrup in The Design and Evolution of C++, it's actually character (pg. 187).   ;  Thanks Zahlman,Obviously your way is much more elegant and safe. I adopted it!;Quote:Original post by SiCraneQuote:Original post by ZahlmanI'm pretty sure it's "console output", actually. After all, to the extent that any output can be said to be composed of characters, it all is. :)According to Bjarne Stroustrup in The Design and Evolution of C++, it's actually character (pg. 187).My mind is officially blown. I always thought it was "console output" as well.   ;  Imagine that. Wonder what he was thinking :S   