Home > Archive > VC STL > April 2005 > copy a list in 1 instruction
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
copy a list in 1 instruction
|
|
| Jürgen Devlieghere 2005-04-12, 4:01 pm |
| A very simple question:
If we have a struct:
struct SContactProperty
{
public:
SContactProperty(void) : m_strName(""), m_strValue(""),
m_bHidden(false) {};
std::string m_strName; //The name of the call property
std::string m_strValue; //The value of the call property
bool m_bHidden;
};
if we have 2 variables l1 and l2, both of type std::list<SContactProperty>,
can
one then do simply:
l1=l2;
???
I ask because a program crashes occasionally. We put GlobalFlags on, and
this should result in the program crashing immediately on the first memory
misusage. But it points to a line like above.
Jürgen Devlieghere
| |
| Igor Tandetnik 2005-04-12, 4:01 pm |
| "Jürgen Devlieghere" <jdv_ommit_all_this@voxtron.com> wrote in message
news:ba3c0$425bd76b$3e3a641c$17666@news.versatel.net
> If we have a struct:
> struct SContactProperty
> {
> public:
> SContactProperty(void) : m_strName(""), m_strValue(""),
> m_bHidden(false) {};
> std::string m_strName; //The name of the call property
> std::string m_strValue; //The value of the call property
> bool m_bHidden;
> };
>
> if we have 2 variables l1 and l2, both of type
> std::list<SContactProperty>, can
> one then do simply:
> l1=l2;
> ???
Yes you can.
> I ask because a program crashes occasionally.
The code you show is fine. The problem must be elsewhere.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
| |
| Jason Winnebeck 2005-04-12, 4:01 pm |
| Is SContactProperty properly copy constructable and assignable (the two
requirements for STL containers)? I'm almost completely positive that
assigning lists like that to make copies is OK.
Actually I see that you have the full struct definition there. I don't see
any reason for an explicit copy ctor or operator = since std::strings are
copyable and bool is a primitive type. So I'm not sure what is wrong.
Jason
Jürgen Devlieghere wrote:
> A very simple question:
>
> If we have a struct:
> struct SContactProperty
> {
> public:
> SContactProperty(void) : m_strName(""), m_strValue(""),
> m_bHidden(false) {};
> std::string m_strName; //The name of the call property
> std::string m_strValue; //The value of the call property
> bool m_bHidden;
> };
>
> if we have 2 variables l1 and l2, both of type std::list<SContactProperty>,
> can
> one then do simply:
> l1=l2;
> ???
> I ask because a program crashes occasionally. We put GlobalFlags on, and
> this should result in the program crashing immediately on the first memory
> misusage. But it points to a line like above.
>
> Jürgen Devlieghere
>
>
| |
| Stephen Howe 2005-04-13, 4:02 am |
| > if we have 2 variables l1 and l2, both of type
> std::list<SContactProperty>, can
> one then do simply:
> l1=l2;
If you have constructed l1 and/or l2 in one executable (EXE/DLL) and the
assignment is taking place in another executable (EXE/DLL) then that can
screw things up if you have done static linking with LIBs for 1+
executable(s).
You need to link with the same RTL in DLL form for both executables or make
sure that any effective allocation/deallocation occurs in one executable
type only.
The other alternative is that you have corrupted the heap/stack. When this
occurs, the program may continue "normally" and may take some while before
the damage shows up. The point where the damage show ups may be innocent and
you need to look at the validity of previous executable statements (and
sometimes a long way back).
Stephen Howe
| |
| Jürgen Devlieghere 2005-04-13, 8:59 am |
| Thanks Stephen,
Everything takes place in the same executable, with no dll's involved. So
that's indeed no problem.
Your remark about a heap corruption that later causes the crash is very
valid. But we used GlobalFlags for that executable to set the allocation
that way that it would crash immediately on the first overwriting of any
allocated space.
This is done much like in e.g.
www.windowsitpro.com/Web/ Article/ArticleID/22962/22962.html
with more info here:
http://www.microsoft.com/technet/pr...9ad55aed63.mspx
Up till now this always served us very well, and any crash was found &
solved very fast. But here it seems not to pinpoint the problem.
Jürgen
"Stephen Howe" <sjhoweATdialDOTpipexDOTcom> wrote in message
news:ea$Chu7PFHA.3196@TK2MSFTNGP12.phx.gbl...
>
> If you have constructed l1 and/or l2 in one executable (EXE/DLL) and the
> assignment is taking place in another executable (EXE/DLL) then that can
> screw things up if you have done static linking with LIBs for 1+
> executable(s).
> You need to link with the same RTL in DLL form for both executables or
> make sure that any effective allocation/deallocation occurs in one
> executable type only.
>
> The other alternative is that you have corrupted the heap/stack. When this
> occurs, the program may continue "normally" and may take some while before
> the damage shows up. The point where the damage show ups may be innocent
> and you need to look at the validity of previous executable statements
> (and sometimes a long way back).
>
> Stephen Howe
>
| |
| Tom Widmer 2005-04-13, 8:59 am |
| Jürgen Devlieghere wrote:
> Thanks Stephen,
>
> Everything takes place in the same executable, with no dll's involved. So
> that's indeed no problem.
>
> Your remark about a heap corruption that later causes the crash is very
> valid. But we used GlobalFlags for that executable to set the allocation
> that way that it would crash immediately on the first overwriting of any
> allocated space.
> This is done much like in e.g.
> www.windowsitpro.com/Web/ Article/ArticleID/22962/22962.html
> with more info here:
> http://www.microsoft.com/technet/pr...9ad55aed63.mspx
>
> Up till now this always served us very well, and any crash was found &
> solved very fast. But here it seems not to pinpoint the problem.
I think that will catch some heap corruption issues immediately, not not
all (as you've discovered). For example, if you corrupt an object, the
corruption might only show up when you attempt to destroy or copy that
object.
Tom
| |
| Stephen Howe 2005-04-13, 4:02 pm |
| > Your remark about a heap corruption that later causes the crash is very
> valid. But we used GlobalFlags for that executable to set the allocation
> that way that it would crash immediately on the first overwriting of any
> allocated space.
> This is done much like in e.g.
> www.windowsitpro.com/Web/ Article/ArticleID/22962/22962.html
> with more info here:
That is not the only way of corrupting the heap.
new/malloc() do sub-allocation so you may corrupt the structure that
new/malloc() use to keep track of allocations without overwriting the big
block of memory obtained from the OS.
Eventually that will cause problems for the heap manager.
There used to be a function called _heapchk() in the Microsoft C library
which was useful in checking that the heap was not corrupt.
For some reason Microsoft eliminated it. A shame.
Heap corruption can occur with
1. Overwriting memory after the last valid byte obtained from
new/malloc()/calloc()/realloc()
2. Underwriting memory before the first valid byte obtained from
new/malloc()/calloc()/realloc() (this is quite rare)
3a. Calling delete on memory obtained by new[]/malloc()/calloc()/realloc()
3b. Calling delete [] on memory obtained by new/malloc()/calloc()/realloc()
3c. Calling free() on memory obtained by new/new[]
On the last three points, new should always be paired with delete, new[]
with delete[] and malloc()/calloc()/realloc() with free(). A gross error to
do otherwise.
4. Calling free(),delete, delete[] more than once on a non-NULL pointer. A
gross error.
5. Calling free(),delete, delete[] on pointers not obtained from
malloc()/calloc()/realloc(), new or new[] respectively. A gross error.
6. Read/Writing to what was once valid memory obtained from
new/new[]/malloc()/calloc()/realloc() but has since been returned to the
heap via delete/delete[]/free().
7. Passing to realloc() a non-NULL pointer not obtained from a previous call
to malloc()/calloc()/realloc()
7. Forgetting that realloc() may return a pointer different from the one
passed.
8. Reusing the old pointer passed to realloc()
9. Forgetting to write a class-specific operator delete if you have written
an operator new.
4 is the one that will gurantee to corrupt the heap as
delete/delete[]/free() of the 1st passed pointer if this results in adjacent
free block merging.
Stephen Howe
| |
| Jürgen Devlieghere 2005-04-15, 4:01 pm |
| Would al these be catched by a product like IDM Rational Purify?
Jürgen
> Heap corruption can occur with
>
> 1. Overwriting memory after the last valid byte obtained from
> new/malloc()/calloc()/realloc()
> 2. Underwriting memory before the first valid byte obtained from
> new/malloc()/calloc()/realloc() (this is quite rare)
> 3a. Calling delete on memory obtained by new[]/malloc()/calloc()/realloc()
> 3b. Calling delete [] on memory obtained by
> new/malloc()/calloc()/realloc()
> 3c. Calling free() on memory obtained by new/new[]
> On the last three points, new should always be paired with delete, new[]
> with delete[] and malloc()/calloc()/realloc() with free(). A gross error
> to
> do otherwise.
> 4. Calling free(),delete, delete[] more than once on a non-NULL pointer. A
> gross error.
> 5. Calling free(),delete, delete[] on pointers not obtained from
> malloc()/calloc()/realloc(), new or new[] respectively. A gross error.
> 6. Read/Writing to what was once valid memory obtained from
> new/new[]/malloc()/calloc()/realloc() but has since been returned to the
> heap via delete/delete[]/free().
> 7. Passing to realloc() a non-NULL pointer not obtained from a previous
> call
> to malloc()/calloc()/realloc()
> 7. Forgetting that realloc() may return a pointer different from the one
> passed.
> 8. Reusing the old pointer passed to realloc()
> 9. Forgetting to write a class-specific operator delete if you have
> written
> an operator new.
>
> 4 is the one that will gurantee to corrupt the heap as
> delete/delete[]/free() of the 1st passed pointer if this results in
> adjacent
> free block merging.
>
> Stephen Howe
>
>
>
| |
| Stephen Howe 2005-04-15, 4:01 pm |
| > Would al these be catched by a product like IDM Rational Purify?
Not sure. I have seen a few messages on products like these, mostly to do
with static global destructors not being called (and this turned out to be
false positives - the product was unware that were being called - very late
in the terminating procedure of an executable)
Have you seen the /GS switch? That catches quite a few memory problems.
It is worth compiling debug builds with this (even release builds for test
purposes)
Stephen Howe
|
|
|
|
|