about std::string

about std::string

Post by V2lsbGlhb » Sat, 23 Jul 2005 07:07:03


{
std::string str;
char buff[4096];
strcpy(buff, "HP Electric Co., Ltd.");
str = buff;
} //I get exception here which is "_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"

Hello, everyone, I get a headache when I debug the code in .net:

1. pHead->nBlockUse is 6 when I get the exception. But this only happen on
my computer. The same code run on other machine in debug mode is fine;
2. if I just copy a string that the size is less than 15, there is no
exception;
3. if I build and run my application in release mode, it is not crash, but I
worry if there is a memory leak;
4. what is the meaning of _Bx._Buf & _Bx._Ptr of std::string?

Thanks for any help.
 
 
 

about std::string

Post by Ulrich Eck » Sat, 23 Jul 2005 16:53:48


Just for your info, that code is ugly but otherwise fine, because "HP..." is
not more than 4096 characters (why such a weird number, btw?).


IIRC, that implementation uses a small, internal buffer (perhaps size =
16?). Only if the string doesn't fit there, it allocates memory
dynamically.


I'm just guessing, one is the pointer to the allocated memory and the other
is the internal, fixed-size buffer. Expect _Bx to be a union of both.

I think the problem is not in your code but rather the way you compile it,
i.e. the environment.

Uli

 
 
 

about std::string

Post by Hendrik Sc » Sat, 23 Jul 2005 18:54:11


What's wrong with
std::string str( "HP Electric Co., Ltd." );
?


I suppose this is a result of some earlier
error. Looks like the heap is messed up.



Schobi

--
XXXX@XXXXX.COM is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett
 
 
 

about std::string

Post by Stephen Ho » Sat, 23 Jul 2005 20:38:37

> not more than 4096 characters (why such a weird number, btw?).

Because it is the page size of a 386+, a power of 2, the default <stdio>
buffer size, even the block size on some hard disks.

Most of my buffer sizes are some multiple of a power of 2.
I would not be using 1000, 2000 or 4000 but 1024, 2048 and 4096.

Not such a weird number :-)

Stephen Howe
 
 
 

about std::string

Post by Stephen Ho » Sat, 23 Jul 2005 20:49:01

> } //I get exception here which is "_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"

Nothing wrong with the code or std::string
You are likely to have damaged the heap at some point of execution further
back.
You need to examine code _BEFORE_ the current execution location for
correctness.

Stephen Howe
 
 
 

about std::string

Post by Ulrich Eck » Sat, 23 Jul 2005 21:18:35


I'm aware of this, but my question stands: why?
Other than that, ATA says block size is 512, IIRC, and this code has nothing
to do with block size of any harddrive whatsoever - could as well use
pi*e*h, that's also cool number.

Seriously, calling that number weird was slightly ironic, but using a power
of two _for no reason_ whatsoever is IMHO worse than not knowing what
buffer size to use.

Uli
 
 
 

about std::string

Post by V2lsbGlhb » Sat, 23 Jul 2005 23:36:07

Hi, Stephen,

1. str is just a local variable, the exception occur in the ~std::string()
(when it try to release the memory). The content of str is right ("HP Electic
Co., Ltd.") before the exception. I realy do not know how this happen. If the
heap has been damaged, how can str alloc the space successfully (??it seems
like that), how can str be used without error?

2. these code can be run before I did some modification, but the exception
still exist even I roll back the code. I rebuild the solution, but not help.
If is the problem of environment, what is your suggestion?
 
 
 

about std::string

Post by V2lsbGlhb » Sat, 23 Jul 2005 23:43:05

Hello, Schobi,

How can I know if the heap is messed up? Are there any way I can try?
 
 
 

about std::string

Post by V2lsbGlhb » Sat, 23 Jul 2005 23:55:05

Hello, Ulrich,

Thanks for your information.

It seems if I trigger std::string to alloc memory in my application,
exception will be appear when distruct the string.
 
 
 

about std::string

Post by Hendrik Sc » Sun, 24 Jul 2005 01:23:30


I suggest you search for postings from Ivan
Brugiolo (of MS) in the language group(s).
Usually he pops up whenever someone asks
about the heap, but he might not read this
group.
Or you use one of the commercially available
tools.



Schobi

--
XXXX@XXXXX.COM is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett
 
 
 

about std::string

Post by Stephen Ho » Wed, 27 Jul 2005 20:55:02

gt; 1. str is just a local variable, the exception occur in the ~std::string()
Electic
the

Because frequently it may be damaged but for a while the heap may appear to
do its job.
But with a damaged heap, various allocations/deallocations may well damage
it further.
Eventually the point comes where the damage is so severe that an illegal
read/write occurs which is trapped by the processor, the OS catches the
exceptions generated and the plug is pulled on your program.

It is rather like shooting someone in the leg.
For a while they might be able to walk.
But if they continue to bleed eventually they will die.


There is nothing wrong with string.
And in all likelyhood there is nothing wrong with your use of it.

But string, vector, deque, list, map, new, malloc(), even fread() all get
memory ultimately from the heap.
And if you have damaged the heap, then they are all potentially affected.

help.

You need to examine your code.
In particular the lines before string's destructor.
Was this in a free function or member function?

From a previous message here:

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()/reallo()
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()/relloc() 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
a class-specific 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.

Also, if you have a class which contains pointers to new'ed memory which you
deallocate in the destructor, then you need to think about the copy
constructor and assignment operator.
The compiler-generated versions will be wrong.
This is sometimes known as the law-of-the-big-3:
If it is essential your class has a user-defined destructor, then the
chances are you need user-defined copy constructor and assignment operator.
If you need 1, you need all 3.
Failure to consider this can lead to heap corruption.

Stephen Howe