|
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
|
|
|
|
|
I'm sure this topic has been discussed to death, I know I've read a number of posts arguing both sides. But I would like some solid evidence supporting both arguments. So, what I've decided to do is write up some routines that will test the collections in both MFC and STL on the same ground. If anyone has knows of similar tests that are on the web or elsewhere, I would greatly appreciate the references.
The output of my tests are below and I would be happy to submit the code if desired. As I am just getting into learning STL (I purchased "The Standard C++ Library" by Nicolai M. Josuttis resently) I am only testing vector against CArray at the moment and only under add and remove of integer values.
There were 6 tests. I first tested vector<int> without reserving any space, then with reserving an equal number of elements as loops - both previous tests using .push_back() - and the third reserving and accessing each element with [].
The next 3 tests were with CArray<int, int>; first without using .SetSize() and using .Add(), the next using .SetSize() and .Add() and the final using .SetSize() and .SetAt().
All values added were the element number * rand()
Are my tests poorly devised? Thank you for any input you can offer.
John
These tests were done with VC6 SP5 on a 1ghz Celeron with 256 megs of RAM
Performing test with 1000000 loops
Added without reserve to Vector<int> in 1.36 seconds
Removed all Vector<int> elements in 0.14 seconds
Added with reserve and push_back to Vector<int> in0.922 seconds
Removed all Vector<int> elements in 0.141 seconds
Added with reserve and [] to Vector<int> in 0.203 seconds
Removed all Vector<int> elements in 0 seconds
Added without SetSize to CArray<int, int> in 252.828 seconds
Removed all CArray elements in 0.031 seconds
Added with SetSize and Add to CArray<int, int> in 768.796 seconds
Removed all CArray elements in 0.047 seconds
Added with SetSize and SetAt to CArray<int, int> in 0.156 seconds
Removed all CArray elements in 0.031 seconds
These tests were performed on a 800MHz Duron with 256 megs of RAM
Performing test with 1000000 loops
Added without reserve to Vector<int> in 1.852 seconds
Removed all Vector<int> elements in 0.181 seconds
Added with reserve and push_back to Vector<int> in1.272 seconds
Removed all Vector<int> elements in 0.18 seconds
Added with reserve and [] to Vector<int> in 0.29 seconds
Removed all Vector<int> elements in 0 seconds
Added without SetSize to CArray<int, int> in 317.226 seconds
Removed all CArray elements in 0.02 seconds
Added with SetSize and Add to CArray<int, int> in 927.173 seconds
Removed all CArray elements in 0.04 seconds
Added with SetSize and SetAt to CArray<int, int> in 0.2 seconds
Removed all CArray elements in 0.02 seconds
|
|
|
|
|
I decided to go ahead and include the test code so anyone can tell me if it is alright or not.
void main()
{
int iLoop = 1000000;
cout << "Performing test with " << iLoop << " loops\r\n";
vector<int> TestVector;
// TestVector.reserve(iLoop);
clock_t Start = clock();
for(int i = 0; i < iLoop; i++){
TestVector.push_back(i * rand());
}
clock_t Finish = clock();
double Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Added without reserve to Vector<int> in " << Time << " seconds\r\n";
Start = clock();
TestVector.clear();
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Removed all Vector<int> elements in " << Time << " seconds\r\n";
/////////////////////////////
TestVector.reserve(iLoop);
Start = clock();
for(i = 0; i < iLoop; i++){
TestVector.push_back(i * rand());
}
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Added with reserve and push_back to Vector<int> in" << Time << " seconds\r\n";
Start = clock();
TestVector.clear();
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Removed all Vector<int> elements in " << Time << " seconds\r\n";
/////////////////////////////
TestVector.reserve(iLoop);
Start = clock();
for(i = 0; i < iLoop; i++){
TestVector[i] = i * rand();
}
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Added with reserve and [] to Vector<int> in " << Time << " seconds\r\n";
Start = clock();
TestVector.clear();
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Removed all Vector<int> elements in " << Time << " seconds\r\n";
/////////////////////////////
CArray<int, int> TestCArray;
Start = clock();
for(int j = 0; j < iLoop; j++){
TestCArray.Add(j * rand());
}
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Added without SetSize to CArray<int, int> in " << Time << " seconds\r\n";
Start = clock();
TestCArray.RemoveAll();
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Removed all CArray elements in " << Time << " seconds\r\n";
/////////////////////////////
// TestCArray.SetSize(iLoop);
// Start = clock();
// for(j = 0; j < iLoop; j++){
// TestCArray.Add(j * rand()); //add's to the end after the .SetSize() elements are added
// }
// Finish = clock();
// Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
// cout << "Added with SetSize and Add to CArray<int, int> in " << Time << " seconds\r\n";
// Start = clock();
// TestCArray.RemoveAll();
// Finish = clock();
// Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
// cout << "Removed all CArray elements in " << Time << " seconds\r\n";
/////////////////////////////
TestCArray.SetSize(iLoop);
Start = clock();
for(j = 0; j < iLoop; j++){
TestCArray.SetAt(j, j * rand());
}
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Added with SetSize and SetAt to CArray<int, int> in " << Time << " seconds\r\n";
Start = clock();
TestCArray.RemoveAll();
Finish = clock();
Time = (double) (Finish - Start) / CLOCKS_PER_SEC;
cout << "Removed all CArray elements in " << Time << " seconds\r\n";
}
|
|
|
|
|
Speed is not the only issue, or even the main one. Time how long it takes to write code for a vector that gets sorted, or shuffled, or partitioned around a point. Now time the same for CArray.
Christian
No offense, but I don't really want to encourage the creation of another VB developer.
- Larry Antram 22 Oct 2002
C# will attract all comers, where VB is for IT Journalists and managers - Michael
P Butler 05-12-2002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not
as easily, but it's certainly doable. - Jamie Nordmeyer - 15-Nov-2002
|
|
|
|
|
Which are you insinuating being faster? Obviously, these types of sorting functions have been implemented already in the different algorythms (I am still reading the book) and to my knowledge nothing has been done about the MFC collections in this regard. So certainly, for this purpose vector would be coded quicker. But I am trying to compare their relative features (you can't serialize a vector without adding the extra code can you?). And to me, if you can predefine the size of the array and move relatively contiguously down its elements, it appears that it is actually faster using the CArray::SetAt() than vector. This is the purpose of my excersize, to see where the benefits are so I can choose my usage wisely.
Has anyone done tests of this nature and published the results and code?
Thank you
John
|
|
|
|
|
lpvoid wrote:
(you can't serialize a vector without adding the extra code can you?).
No, but the code is trivial, and in fact would use one of those algorithms, foreach.
lpvoid wrote:
This is the purpose of my excersize, to see where the benefits are so I can choose my usage wisely.
And my point is that the benefits of vector strip CArray pretty quickly because STL is extensible, compatible ( all containers expose the same sort of iterators ), flexible ( full of function objects which can be extended and modified ), etc.
lpvoid wrote:
Has anyone done tests of this nature and published the results and code?
As I said, I think you need to look at feature lists more than code.
Christian
No offense, but I don't really want to encourage the creation of another VB developer.
- Larry Antram 22 Oct 2002
C# will attract all comers, where VB is for IT Journalists and managers - Michael
P Butler 05-12-2002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not
as easily, but it's certainly doable. - Jamie Nordmeyer - 15-Nov-2002
|
|
|
|
|
Watch out using STL algorithms. They often highly degrade performance. Handwritten loops are much more stable from a performance standpoint. In my tests, STL algorithms can degrade performance by 100-200% over hand written loops. I have rarely seen it perform better than handwritten loops. The problem is in the optimizer and not STL specifically.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Christian,
I understand what you are saying and appreciate your responses. I will continue learning STL because quite frankly, it can't hurt to know it. I see there is a great deal of functionality in the library but at present, I don't have a use for hardly any of it. As for the extensibility of vector (and STL in general), CArray (and MFC in general) is extensible as well.
Thank you for your time and comments,
John
|
|
|
|
|
lpvoid wrote:
As for the extensibility of vector (and STL in general), CArray (and MFC in general) is extensible as well.
I was not thinking of deriving classes, you can do that most of the time in C++. I was thinking of being able to create a container, which can then interact with all the stl containers, creating a function object and being able to modify several functions with it, across several containers. MFC containers are not even compatibile with each other.
Christian
No offense, but I don't really want to encourage the creation of another VB developer.
- Larry Antram 22 Oct 2002
C# will attract all comers, where VB is for IT Journalists and managers - Michael
P Butler 05-12-2002
Again, you can screw up a C/C++ program just as easily as a VB program. OK, maybe not
as easily, but it's certainly doable. - Jamie Nordmeyer - 15-Nov-2002
|
|
|
|