[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

dumping content of an object

Posted on 2002-05-13
25
Medium Priority
?
1,007 Views
Last Modified: 2013-12-14
is there any better way of dumping content of an object on screen/debugger watch window in vc++ debugger.
in case of STL objects, the debugger watch window is really painful.

I'm not willing to use autoexp.dat file.
0
Comment
Question by:prashant_n_mhatre
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 14
  • 6
  • 2
  • +2
25 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 7007302
>> really painful
I agree, and this is one of the prime reasons that I refuse to use STL.  The other is that tracing through the source code is excruciating.  Simple program errors that should take a few minutes to isolate and debug turn into all-night marathons.  

Contrast the std::string class to MFC's CString.  Both have similar features.  But with the latter, the code is clear and the data is at your fingertips.

About the only thing you can do is write a custom object-dumper.  It's output can go to the Debug window (TRACE) or to a log file.  The alternaive is avoid STL.

-- Dan
0
 
LVL 30

Expert Comment

by:Axter
ID: 7007309
The problem is not with STL, but with the IDE.

VC++ IDE is clearly gear towards MFC, and makes little effort to interface properly with STL code.
0
 
LVL 2

Expert Comment

by:xLs
ID: 7007367
i guess you are aware that watch window does intepretation as if it was runtime code.
so code casting and depth mem accessing can be made within the watch window..

such as a typical stl watch:

// depending on the template class

((CMyClass*) (*myiterator))->m_arrayinclass[mycounter];
or dumping complete class (without the stl jumbo)

(CMyClass*) *myiterator;

i agree STL "was" painful to debug.. but its all about getting used to and learn a good way to debug it.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 30

Expert Comment

by:Axter
ID: 7007377
Here's some code for putting some STL types to your TRACE window.

#pragma warning (disable:4786)
#include <sstream>
#include <string>

#ifdef _DEBUG
namespace DEBUG_CODE
{
     template<typename T>
     void TraceSTL_Obj(const char* SourceFileName, int SourceLineNum, const char* ObjectName, T t, int Index = -1)
     {
          std::ostringstream oss;
          oss << SourceFileName << "(" << SourceLineNum << ") : {" << ObjectName;
          if (Index > -1) oss << "[" << Index << "]";
          oss << "} = " << t << std::endl;
          TRACE(oss.str().c_str());
     }
     template<typename T>
     void TraceSTL_Container(const char* SourceFileName, int SourceLineNum, const char* ObjectName, T t)
     {
          int Idx = 0;
          for (T::const_iterator i = t.begin();i != t.end();++i, ++Idx)
          {
               std::string szObjectName = ObjectName;
               TraceSTL_Obj(SourceFileName, SourceLineNum, ObjectName, *i, Idx);
          }
     }
     template<typename T>
     void TraceSTL_AsscContainer(const char* SourceFileName, int SourceLineNum, const char* ObjectName, T t)
     {
          int Idx = 0;
          for (T::const_iterator i = t.begin();i != t.end();++i, ++Idx)
          {
               std::string szObjectName = ObjectName;
               TraceSTL_Obj(SourceFileName, SourceLineNum, ObjectName, i->first, Idx);
          }
     }
}
#define TRACE_STL_OBJ(t)              DEBUG_CODE::TraceSTL_Obj(__FILE__, __LINE__, #t, t)
#define TRACE_STL_CONTAINER(t)              DEBUG_CODE::TraceSTL_Container(__FILE__, __LINE__, #t, t)
#define TRACE_STL_ASSC_CONTAINER(t)              DEBUG_CODE::TraceSTL_AsscContainer(__FILE__, __LINE__, #t, t)
#else //_DEBUG
#define TRACE_STL_OBJ(t)            
#define TRACE_STL_CONTAINER(t)            
#define TRACE_STL_ASSC_CONTAINER(t)
#endif //_DEBUG
0
 
LVL 30

Expert Comment

by:Axter
ID: 7007381
Example usage:
#pragma warning (disable:4786)
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <deque>
#include <map>

CTestTraceSTLApp::CTestTraceSTLApp()
{
     std::vector<std::string> MyStringVect;
     MyStringVect.push_back("Test1");
     MyStringVect.push_back("Test2");
     MyStringVect.push_back("Test3");
     MyStringVect.push_back("Test4");
     TRACE_STL_CONTAINER(MyStringVect);

     std::list<std::string> MyStringList;
     MyStringList.push_back("Testx1");
     MyStringList.push_back("Testx2");
     MyStringList.push_back("Testx3");
     TRACE_STL_CONTAINER(MyStringList);

     std::map<int, std::string> MyStringMap;
     MyStringMap[69] = "Test69";
     MyStringMap[77] = "Test77";
     MyStringMap[33] = "Test33";
     TRACE_STL_ASSC_CONTAINER(MyStringMap);

     std::string test1 = "Hello World! from std::string";
     TRACE_STL_OBJ(test1);

     CString test2 = "Hello World! from CString";
     TRACE_STL_OBJ(test2);
        AfxMessageBox("Check your debug window for above data");
}
0
 
LVL 6

Expert Comment

by:snoegler
ID: 7008636
0
 
LVL 6

Expert Comment

by:snoegler
ID: 7008639
Ooops sorry i didn't see the last line in your question :)
0
 
LVL 4

Author Comment

by:prashant_n_mhatre
ID: 7009511
Thank you all.

I tried out a small test program

//----------------------------------
#pragma warning (disable:4786)
#include <string>
#include <list>
#include <iostream>
using namespace std;

typedef list<string> STRINGLIST;


void main()
{
     STRINGLIST  m_IssueList;
         
     m_IssueList.insert(m_IssueList.end(), "AAA");
     m_IssueList.insert(m_IssueList.end(), "BBB");
     m_IssueList.insert(m_IssueList.end(), "CCC");
         
     STRINGLIST::iterator Issues;
     
     for(Issues = m_IssueList.begin(); Issues != m_IssueList.end(); Issues++)
     {
          cerr << *Issues << endl;
     }
     
}
//-------------------------------------

What is the simplest way to see the content of (*Issues) and m_IssueList in debugger watch window?
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009523
Use the STL trace code I posted above.
TRACE_STL_ASSC_CONTAINER(m_IssueList);


TRACE_STL_OBJ(*Issues);
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009525
Correction:
TRACE_STL_CONTAINER(m_IssueList);


TRACE_STL_OBJ(*Issues);
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009528
Or you can modify your code to the following:
for(Issues = m_IssueList.begin(); Issues != m_IssueList.end(); Issues++)
    {
         //cerr << *Issues << endl;
         TRACE("%s",Issues->c_str());
    }
0
 
LVL 4

Author Comment

by:prashant_n_mhatre
ID: 7009576
TRACE doesn't work in console application. Do I need to write my own TRACE macro?

I guess simple 'printf' will work.
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009593
TRACE does work from a console application:
You need to include "afx.h"

Example:

#include "stdafx.h"

#include <stdlib.h>

#include <afx.h>

int main(int argc, char* argv[])
{
     TRACE("Hello from TRACE");

     system("pause");
     return 0;
}
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009601
You might need to modify your project settings under C++ TAB and [Code Generation], and change run-time library to Multithread.

Only do this if you get errors like the following:
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
0
 
LVL 4

Author Comment

by:prashant_n_mhatre
ID: 7009603
Do I need to create win32 application? I tried including <afx.h> in console application. It gives linking error like:

Linking...
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in libcpd.lib(delop.obj)
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
Debug/kkSTL.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

0
 
LVL 30

Expert Comment

by:Axter
ID: 7009618
As I stated in previous comment, you need to modify your project settings under C++ TAB and [Code Generation], and change run-time
library to Multithread.
0
 
LVL 4

Author Comment

by:prashant_n_mhatre
ID: 7009659
Oops...Your comment was not there when I'd started typing my last comment. I did the same you suggested..still getting the following error..

Linking...
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in libcpmtd.lib(delop.obj)
LINK : warning LNK4098: defaultlib "LIBCMT" conflicts with use of other libs; use /NODEFAULTLIB:library
Debug/kkSTL.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.


tried using /NODEFAULTLIB -- doesn't work
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009685
OK, lets change TRACE to what it should be.
Use OutputDebugString instead for CONSOLE.

And replace "afx.h" with the following includes:
#include <windows.h>
#include <Winbase.h>

Also you can change you project setting back to single thread.
0
 
LVL 4

Author Comment

by:prashant_n_mhatre
ID: 7009694
No link error...but no output getting displayed on screen.
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009702
#include <windows.h>
#include <Winbase.h>

If you use OutputDebugString, you can't just use it like TRACE, because OutputDebugString, takes a single string, and not a variable argument type.

You can use the code I posted, and just change TRACE to OutputDebugString.

0
 
LVL 30

Expert Comment

by:Axter
ID: 7009703
Try createing a new test console application, and paste the following code into the main.cpp file:

#include "stdafx.h"

#include <windows.h>
#include <Winbase.h>


#pragma warning (disable:4786)
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <deque>
#include <map>

#ifdef _DEBUG
namespace DEBUG_CODE
{
     template<typename T>
     void TraceSTL_Obj(const char* SourceFileName, int SourceLineNum, const char* ObjectName, T t, int Index = -1)
     {
          std::ostringstream oss;
          oss << SourceFileName << "(" << SourceLineNum << ") : {" << ObjectName;
          if (Index > -1) oss << "[" << Index << "]";
          oss << "} = " << t << std::endl;
          OutputDebugString(oss.str().c_str());
     }
     template<typename T>
     void TraceSTL_Container(const char* SourceFileName, int SourceLineNum, const char* ObjectName, T t)
     {
          int Idx = 0;
          for (T::const_iterator i = t.begin();i != t.end();++i, ++Idx)
          {
               std::string szObjectName = ObjectName;
               TraceSTL_Obj(SourceFileName, SourceLineNum, ObjectName, *i, Idx);
          }
     }
     template<typename T>
     void TraceSTL_AsscContainer(const char* SourceFileName, int SourceLineNum, const char* ObjectName, T t)
     {
          int Idx = 0;
          for (T::const_iterator i = t.begin();i != t.end();++i, ++Idx)
          {
               std::string szObjectName = ObjectName;
               TraceSTL_Obj(SourceFileName, SourceLineNum, ObjectName, i->first, Idx);
          }
     }
}
#define TRACE_STL_OBJ(t)              DEBUG_CODE::TraceSTL_Obj(__FILE__, __LINE__, #t, t)
#define TRACE_STL_CONTAINER(t)              DEBUG_CODE::TraceSTL_Container(__FILE__, __LINE__, #t, t)
#define TRACE_STL_ASSC_CONTAINER(t)              DEBUG_CODE::TraceSTL_AsscContainer(__FILE__, __LINE__, #t, t)
#else //_DEBUG
#define TRACE_STL_OBJ(t)            
#define TRACE_STL_CONTAINER(t)            
#define TRACE_STL_ASSC_CONTAINER(t)
#endif //_DEBUG


int main(int argc, char* argv[])
{
     std::vector<std::string> MyStringVect;
     MyStringVect.push_back("Test1");
     MyStringVect.push_back("Test2");
     MyStringVect.push_back("Test3");
     MyStringVect.push_back("Test4");
     TRACE_STL_CONTAINER(MyStringVect);

     std::list<std::string> MyStringList;
     MyStringList.push_back("Testx1");
     MyStringList.push_back("Testx2");
     MyStringList.push_back("Testx3");
     TRACE_STL_CONTAINER(MyStringList);

     std::map<int, std::string> MyStringMap;
     MyStringMap[69] = "Test69";
     MyStringMap[77] = "Test77";
     MyStringMap[33] = "Test33";
     TRACE_STL_ASSC_CONTAINER(MyStringMap);

     std::string test1 = "Hello World! from std::string";
     TRACE_STL_OBJ(test1);

     
     system("pause");
     return 0;
}

0
 
LVL 30

Accepted Solution

by:
Axter earned 400 total points
ID: 7009706
I just tested the above code.
You'll see the out put in your debug window.  Make sure you have the debug tab selected in your output window.
0
 
LVL 30

Expert Comment

by:Axter
ID: 7009713
Or you can modify your code to the following:
for(Issues = m_IssueList.begin(); Issues != m_IssueList.end(); ++Issues)//You should practice using prefix
   {
        //cerr << *Issues << endl;
        OutputDebugString(Issues->c_str());
   }
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7009777
The simplest way to see it in the Watch window would look like this:

char* pTmp;
for(Issues = m_IssueList.begin(); Issues != m_IssueList.end(); Issues++)
    {
         pTmp= Issues->c_str();
    }

Then put a watch on pTmp.  Or just rest the mouse over it and an infotip will pop up!  You could even use:

     #if _DEBUG
            pTmp= Issues->c_str();
     #endif

so that it won't interfere with the release build.

-- Dan
0
 
LVL 4

Author Comment

by:prashant_n_mhatre
ID: 7013699
Thank you all !!!
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand column That will then direct you to their download page. From that p…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

649 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question