|
I program an app that uses a treeCtrl, and I use the tv_item::lParam save an address of an item in std::list. Code like this:
std::list<MyStruct> items;
....
std::list<MyStruct>::iterator pCur = items.begin();
TVM_INSERTITEM tvi;
tvi.item.mask = TVIF_TEXT | TVIF_PARAM...
tvi.item.lParam = &(*pCur);
....
TreeView_InsertItem(hTree, &tvi);
....
when I retrive an item of the tree and its MyStruct:
MyStruct* pMyStruct;
TV_ITEM item;
item.mask = TVIF_TEXT|TVIF_PARAM...
TreeView_GetItem(hTree, &item);
pMyStruct = (MyStruct*)item.lParam;
Now, the pMyStruct is not equal the &(*pCur) above.
How can I prohibit STL alter its items' addresses?
|
|
|
|
|
Well, std::list guarantees that addresses of their elements won't change (unless you delete them, of course). Do you mean that pMyStruct is not equal to the value tvi.item.lParam as it stood before calling TreeView_InsertItem ? If so, your problem lies elsewhere, and in fact does not have to do with std::list : basically, you're not getting the value you previously set in tvi.item.lParam .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
My problem is following.
I have a template MyTemplate
template <typename t="">
class MyTemplate
{
/////////////some members;
};
and I want to declare a vector whose elements would be of type MyTemplate.
It should be code like this (as I expect)
vector< MyTemplate<t> > MyVector;
But this of course does not compiled.
Where is my mistake?
Could anyone of gurus help me?
|
|
|
|
|
Visual C++ does not support templates as template parameters. Remember, template is not a type. You create a type from a template by providing template parameters.
|
|
|
|
|
template <typedef P>
class MyTemplate
{
public:
MyTemplate() {};
P m_Data;
};
typedef MyTemplate<int> MyIntTemplate;
std::vector<MyIntTemplate> MyIntTemplateVecotr;
Todd Smith
|
|
|
|
|
Just an FYI to everyone:
std::vector <MyTemplate<int> > MyIntTemplateVector;
Works just fine. The thing you have to watch out for is not including a space between the two >>.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Thank you Nemanja, thank you Todd, thank you Tim!
Of course I am familiar with answers proposed by Todd and Tim.
If I define a type of my template first, say
typedef MyTemplate<int> intMyTemplate;
and then define
typedef std::vector<intMyTemplate> intMyVector;
or even shorter
typedef std::vector< MyTemplate<int> > intMyVector;
all the rest will work fine.
But my goal is just to write some construction that would enable me
to define a vector in the fashion like this:
typedef MyVector<T> TMyVector;
and will produce an std::vector< MyTemplate<t> > which contains
elements of type of MyTemplate<t>.
I was trying to use something like this:
template<class T, template<class> class container=std::vector><br />
struct MyVector<br />
{<br />
container<T> m_container;<br />
};
but this code dosn't compile in VC60. Nemanja wrote that VC compiler
dosn't support template-templates. May be some service pack will help?
Or gurus could propose some other resolution?
Thank to all anyway!
|
|
|
|
|
Biochemist wrote:
template class container=std::vector>
struct MyVector
{
container m_container;
};
You're close, the problem is that there is no class called std::vector . std::vector is a template, not a class. You don't have a class until you create a specialization of std::vector , such as std::vector<int> .
So what I think you have in mind is:
template <typename ELEMENT, typename container = std::vector<ELEMENT> >
struct MyVector
{
container m_container;
};
--Mike--
I'm bored... Episode I bored.
1ClickPicGrabber - Grab & organize pictures from your favorite web pages, with 1 click!
My really out-of-date homepage
Sonork-100.19012 Acid_Helm
|
|
|
|
|
Mike, what Biochemist wants is perfectly valid from the standard C++ point of view. It is called template template parameters , but it is not supported by VC++ 6.0 or 7.0. Microsoft promises that VC 7.1 will have them.
|
|
|
|
|
Nemanja Trifunovic wrote:
but it is not supported by VC++ 6.0 or 7.0.
I don't think that's entirely true, VC 7.0 does currently support template template parameters. The following compiles fine for me in VC 7.0:
template<
template<typename, typename> class Container = std::vector,
template<typename> class Allocator = std::allocator
>
struct number_holder {
Container<int, Allocator<int> > numbers_;
};<
cheers,
-B
|
|
|
|
|
Biochemist wrote:
Or gurus could propose some other resolution?
Not that I am a guru, but I think you could use good old macros to accomplish this.
Or wait for VC 7.1 to be released.
|
|
|
|
|
|
|
Actually it does only go foward.
Starting at first, it counts "n" into the collection and tests that item. If test fails, it moves first to the current position. Otherwise, it just keep first as is.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Could someone please explain why the following code sample leaks memory?
void main(void)
{
int nLoop = 0;
while(nLoop < 50000)
{
MainTestStub06();
nLoop++;
Sleep(10);
}
}
void MainTestStub06(void)
{
USES_CONVERSION;
CComBSTR bstrTagName("Hello World");
std::string strTemp = OLE2A(bstrTagName);
bstrTagName.Empty();
}
What appears to leak memory is the call to OLE2A. Remove the line and all works well. The CComBSTR releases itself once it goes out of scope.
|
|
|
|
|
It is not real leak, it is stack memory usage by Microsoft implementation of CRT. OLE2T and the rest use alloca, which is stack memory allocation. From my observation memory allocated with alloca released only when there is some internal limit reached, not like it is clamed by MS : "The allocated space is automatically freed when the calling function exits" (MSDN).
So code like
for(int i = 0; i < 10000;++i)
char* p = (char*)alloca(100);
Will increase your memory usage.
If you are concerned with that use _bstr_t (<comdef.h>)
|
|
|
|
|
The MSDN documents are 100% correct. Alloca memory is released when the calling function returns. After all, it is just stack space.
The reason you don't see the memory deallocated when OLE2A returns is because it is a macro, not a routine.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
What does macro have to do with it? Macro or not , go to task manager and see memory grow for your process every time you use alloca. BoundsChecker and Purify both report memory leaks at OLE2... location, though they are not consistent, that is they do not report it for all instances.
|
|
|
|
|
A macro has a lot to do with alloca. Alloca reserves STACK SPACE which will be deallocated by a return. I ran the given example and there ARE NO MEMORY LEAKS.
You can get yourself into trouble with OLE2 etal if you use it inside of a loop. Each iteration will allocate more stack space. However, if you place body of the loop in a subroutine, then it is safe to use alloca.
EDIT: This is one of the reasons alloca and inlining can't be used together.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
I agree example is bad, first you probably run out of the stack space, second the chunk is so big that it is probably deallocated right the way(upon function exit). The macro argument I still do not get (forgive me I am probably too slow ). We can argue this issue for long time, but I've seen this issue many times, spent many days to hunt down "non existent memory leak". Memory usually released at some point I agree, but it is not much help when you need to explain to your customer why repeated operation "eats up" 20K, 30K ....
|
|
|
|
|
No, in the example posted, you don't run out of stack space. I even invoked the routine millions of times. You are blaming the wrong thing. When used prioperly (i.e. not repeatedly without returning from a routine), alloca does not leak memory. It can't. Once you return from the routine, alloca memory is freed. This is why you can never return an alloca buffer to a calling routine.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
|
Hi,
is there a way that my app could connect to the Internet and then execute a script (ex: mypage.com/script.asp?var1=10&var2=yes) without having to run it in a browser?
Then, this script would return some data as a stream, just like a regular web page would, execpt that i'd store the data in a variable, not display it in a browser...
I guess I could use CInternetSession/CInternetConnection with MFC, but I want to do it with ATL...
Thanks!
---------------
Tired of Spam? Introducing InboxShield® for Microsoft® Outlook®
http://www.edovia.com
|
|
|
|
|
See MSDN for CBindStatusCallback and IBindStatusCallback. CBindStatusCallback was designed to handle file downloads, but should handle HTTP post and get (this is eventually what you are looking for, ASP or not is irrelevant).
|
|
|
|
|
see URLDownloadToFile (requires urlmon.dll) or you could use your own HTTP class. There are several on CP.
Todd Smith
|
|
|
|