I am extending the Visual Studio 2003 debugger using autoexp.dat and a DLL to improve the way it displays data in the watch window. The main reason I am using a DLL rather than just the basic autoexp.dat functionality is that I want to be able to display things conditionally. e.g. I want to be able to say "If the name member is not an empty string, display name, otherwise display [some other member]"
I'm quite new to OOP and haven't got any experience with the STL. So it might be that I'm missing the obvious.
I'm having trouble displaying vector members because I don't know how to get the pointer to the memory the actual values are stored in.
Am I right in thinking the values are stored in a contiguous block of memory? And is there any way to get access to the pointer to that memory?
Thanks!
[edit:] To clarify my problem (I hope):
In my DLL, which is called by the debugger, I use a function called ReadDebuggeeMemory which makes a copy of the memory used by an object. It doesn't copy the memory the object points to. So I need to know the actual address value of the internal pointer in order to be able to call ReadDebuggeeMemory on that as well. At the moment, the usual methods of getting the vector contents are returning garbage because that memory hasn't been copied yet.
[update:]
I was getting garbage, even when I was looking at the correct pointer _Myfirst because I was creating an extra copy of the vector, when I should have been using a pointer to a vector. So the question then becomes: how do you get access to the pointer to the vector's memory via a pointer to the vector? Does that make sense?
I couldn't implement the solutions suggested by Gman and Roddy once I changed from having a vector variable to having a pointer to a vector, quite probably because I'm just too clueless.
I have found the pointer I was looking for though: _Myfirst
So my code works when I use
I'm surprised that I've got access to _Myfirst. I would have expected it to be a private member. But obviously not...
Yes, The values are stored in a contiguous area of memory, and you can take the address of the first element to access it yourself.
However, be aware that operations which change the size of the vector (eg push_back) can cause the vector to be reallocated, which means the memory may move, invalidating your pointer. The same happens if you use iterators.
You couldn't implement the solutions suggested by Gman and Roddy because they answers, seemingly correct, but has nothing to do with you situation.
When developing an Addin Dll for Expression Evaluation (EE) to use with autoexp.dat, you are getting one raw pointer to the vector object from your process. But the Dll is running in the process of Visual Studio Debugger, so the only way to access the vector's data is through the ReadDebuggeeMemory function.
You should use that raw pointer and ReadDebuggeeMemory() to read the memory occupied by an object in Debugee process to the local buffer/object. (local for Debugger process, meaning your dll). Then get necessary data from local object, if it is a pointer, than you have to use ReadDebuggeeMemory() again, to read the object pointed by it to another local location. And so on.
For vector's (I haven't done it myself to be more specific), you should 1. Read (ReadDebuggeeMemory()) the vector object to the local one. 2. Get the size of the vector (I assume it is a non pointer data in vector class) 3. Get the pointer to that the contiguous memory location, and read (ReadDebuggeeMemory()) that block to the local buffer/block. Block size is sizeof(VectorType) * VectorSize in bytes. (if it is not continuous, then things will be more complicated, but the idea is the same). 4. Since your vector contains pointers, you have to read (ReadDebuggeeMemory()) every item separately into local memory.
The elements in a standard vector are allocated as one contiguous memory chunk.
You can get a pointer to the memory by taking the address of the first element, which can be done is a few ways:
However unless you need to pass the underlying array around to some old interfaces, generally you can just use the operators on vector directly.
Note that you can only access up to
vec.size()
elements of the returned value. Accessing beyond that is undefined behavior (even if you think there is capacity reserved for it).If you had a pointer to a vector, you can do the same thing above just by dereferencing:
Better yet though, try to get a reference to it.
About your solution
You came up with the solution:
The only time this will work is on that specific implementation of that specific compiler version. This is not standard, so this isn't guaranteed to work between compilers, or even different versions of your compiler.
It might seem okay if you're only developing on that single platform & compiler, but it's better to do the the standard way given the choice.