468,512 Members | 1,448 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,512 developers. It's quick & easy.

Runtime error - _CrtIsValidHeapPointer(pUserData)

Hi,

I have defined a very simple class as follows. I initialize the
CInventory object as: CInventory *itemInveotry;

The program just performs two functions - it reads the total number of
items and values of itemNumber, quantity and cost per item from the
user, and it prints these values back.

While printing these values, I get a _CrtIsValidHeapPointer(pUserData)
exception if I use a statement like:

for (int i = 1; i <= numItems; i++)
(itemInventory + i)->printItem();

However, if I modify the for statement to the one below, the program
works perfectly.

for (int i = 0; i <= numItems - 1; i++)
(itemInventory + i)->printItem();

Can anyone tell me why the same program works fine for one for loop, but
not for the other (equivalent?) for loop?

When the application does fail I get the following error right before
the _CrtIsValidHeapPointer:
HEAP CORRUPTION DETECTED: after Normal block (#143) CRT Detected
application wrote to memory after end of heap buffer

Thanks in advance,
Schiz

class CInventory {

private:
int itemNumber; // holder the item's item number
int quantity; // in-stock item quantity
double cost; // storage cost per item
double totalCost; // total inventory cost

public:
// set the input info for each item
void setItem(int, int, double);
// print the item info
void printItem(void);
};
Oct 23 '06 #1
13 8448
Hello,
I can't answer your question sorry, but I have a question about your
code instead.

Schizoid Man wrote:
Hi,

I have defined a very simple class as follows. I initialize the
CInventory object as: CInventory *itemInveotry;

The program just performs two functions - it reads the total number of
items and values of itemNumber, quantity and cost per item from the
user, and it prints these values back.

While printing these values, I get a _CrtIsValidHeapPointer(pUserData)
exception if I use a statement like:

for (int i = 1; i <= numItems; i++)
Is the line below really legal without overloading "+"? If so, what
does it mean? sorry for a noob question ^^'
(itemInventory + i)->printItem();

However, if I modify the for statement to the one below, the program
works perfectly.

for (int i = 0; i <= numItems - 1; i++)
(itemInventory + i)->printItem();

Can anyone tell me why the same program works fine for one for loop, but
not for the other (equivalent?) for loop?

When the application does fail I get the following error right before
the _CrtIsValidHeapPointer:
HEAP CORRUPTION DETECTED: after Normal block (#143) CRT Detected
application wrote to memory after end of heap buffer
PS. in my opinion, this may be the error of your compiler coz
allocating memory should be a compiler's job. A programmer cannot
explicitly allocate memory himself ( or there is such a function? not
sure :P ).
Hope might help.

>
Thanks in advance,
Schiz

class CInventory {

private:
int itemNumber; // holder the item's item number
int quantity; // in-stock item quantity
double cost; // storage cost per item
double totalCost; // total inventory cost

public:
// set the input info for each item
void setItem(int, int, double);
// print the item info
void printItem(void);
};
-O.Kittipot

Oct 23 '06 #2
Schizoid Man wrote:

[snip]
While printing these values, I get a _CrtIsValidHeapPointer(pUserData)
exception if I use a statement like:

for (int i = 1; i <= numItems; i++)
(itemInventory + i)->printItem();

However, if I modify the for statement to the one below, the program
works perfectly.

for (int i = 0; i <= numItems - 1; i++)
(itemInventory + i)->printItem();

Can anyone tell me why the same program works fine for one for loop, but
not for the other (equivalent?) for loop?
Maybe you should take your C++ Primer down from your bookshelf and do
some serious re-reading. C or C++ arrays are _always_ accessed starting
from index zero up the size of the array minus one. Your second loop
will try to read memory that lies outside the array, and luckily this is
caught by the run-time checking facility of your compiler.

Regards,
Stuart
Oct 23 '06 #3
Kouisawang wrote:
Hello,
I can't answer your question sorry, but I have a question about your
code instead.

Schizoid Man wrote:
>>
for (int i = 1; i <= numItems; i++)

Is the line below really legal without overloading "+"? If so, what
does it mean? sorry for a noob question ^^'

>> (itemInventory + i)->printItem();
Operator+ is already overloaded for pointers. Depending on the actual
type that is pointed to, operator+ for pointers will behave like this:

T* operator+ (T* BaseAddress, int Offset)
{
return (T*) int (BaseAddress) + sizeof (T) * Offset;
}
>
PS. in my opinion, this may be the error of your compiler coz
allocating memory should be a compiler's job. A programmer cannot
explicitly allocate memory himself ( or there is such a function? not
sure :P ).
Hope might help.
Are you by any chance a Java programmer? Google for "operator new", or
buy a text book about C++. Any will do.

Stuart

Oct 23 '06 #4

Stuart Redmann wrote:
Schizoid Man wrote:

[snip]
While printing these values, I get a _CrtIsValidHeapPointer(pUserData)
exception if I use a statement like:

for (int i = 1; i <= numItems; i++)
(itemInventory + i)->printItem();

However, if I modify the for statement to the one below, the program
works perfectly.

for (int i = 0; i <= numItems - 1; i++)
(itemInventory + i)->printItem();

Can anyone tell me why the same program works fine for one for loop, but
not for the other (equivalent?) for loop?

Maybe you should take your C++ Primer down from your bookshelf and do
some serious re-reading. C or C++ arrays are _always_ accessed starting
from index zero up the size of the array minus one. Your second loop
will try to read memory that lies outside the array, and luckily this is
caught by the run-time checking facility of your compiler.
Of course!!! If I initialize i = 1, then the method call should be:
(itemInventory + i - 1)->printItem();

Thanks for the help.

Oct 23 '06 #5

Stuart Redmann wrote:
Kouisawang wrote:
Hello,
I can't answer your question sorry, but I have a question about your
code instead.

Schizoid Man wrote:
>
for (int i = 1; i <= numItems; i++)
Is the line below really legal without overloading "+"? If so, what
does it mean? sorry for a noob question ^^'

> (itemInventory + i)->printItem();
-----------------------------------------------------------------------------------------------------------------
So you mean all pointers already have overload "+" operation even
though
that pointer that doesn't belong to the predefined or primary
class/type?
Sorry again about noob question, I know just little about c++ and wanna
study more.
-----------------------------------------------------------------------------------------------------------------
Operator+ is already overloaded for pointers. Depending on the actual
type that is pointed to, operator+ for pointers will behave like this:

T* operator+ (T* BaseAddress, int Offset)
{
return (T*) int (BaseAddress) + sizeof (T) * Offset;
}

PS. in my opinion, this may be the error of your compiler coz
allocating memory should be a compiler's job. A programmer cannot
explicitly allocate memory himself ( or there is such a function? not
sure :P ).
Hope might help.

Are you by any chance a Java programmer? Google for "operator new", or
buy a text book about C++. Any will do.

Stuart
Oct 23 '06 #6

Stuart Redmann wrote:
Schizoid Man wrote:

[snip]
While printing these values, I get a _CrtIsValidHeapPointer(pUserData)
exception if I use a statement like:

for (int i = 1; i <= numItems; i++)
(itemInventory + i)->printItem();

However, if I modify the for statement to the one below, the program
works perfectly.

for (int i = 0; i <= numItems - 1; i++)
(itemInventory + i)->printItem();

Can anyone tell me why the same program works fine for one for loop, but
not for the other (equivalent?) for loop?

Maybe you should take your C++ Primer down from your bookshelf and do
some serious re-reading. C or C++ arrays are _always_ accessed starting
from index zero up the size of the array minus one. Your second loop
will try to read memory that lies outside the array, and luckily this is
caught by the run-time checking facility of your compiler.

Regards,
Stuart
You are right that the array is out of bound. However, most compiler I
use don't show this type of error, so I didn't check carefully about
this point. Usually you can manipulate the out of bound array but what
you get is just the garbage that have been used by the previous
program.

for example.

int a[10] = {0};

for(int i=0; i<10; i++){
cout << "This is a[" << i+1 << "]:" << a[i+1] << endl;
}

you have accessed the a[10], which is not a valid member of our array
but this program won't crash; it will show some garbage for a[10]
instead.
And what do you mean by

"C or C++ arrays are _always_ accessed starting from index zero up the
size of the array minus one."?

Can't we start accessing form any other positions in an array?
>From the code above, I don't think there will be a problem if we change
from "for(int i=0;.....)"
to "for(int i=2, .....)". so not sure what do you mean by that.

This may be happen only for my compilers, gcc, Dev-C++, and VisualC++
2005(express).
What is your compiler, I want to try if it can catch the out of bound
array? I may have to migrate to it. :^)

Thanks in advance.

Oct 23 '06 #7

Kouisawang wrote:
You are right that the array is out of bound. However, most compiler I
use don't show this type of error, so I didn't check carefully about
this point. Usually you can manipulate the out of bound array but what
you get is just the garbage that have been used by the previous
program.
Ususally, perhaps. But not necessarily always.
for example.

int a[10] = {0};

for(int i=0; i<10; i++){
cout << "This is a[" << i+1 << "]:" << a[i+1] << endl;
}

you have accessed the a[10], which is not a valid member of our array
correct
but this program won't crash;
It might well crash. Nothing about the code says that a crah is
mpossible.
it will show some garbage for a[10] instead.
It might do that too. a is an array of 10 ints, indexed by values 0 to
9. An attempt to access a[10] invokes undefined behavior. That means
that *absolutely anything* is possible. Of the allowed infinite number
of different outcomes, two possibilities are:

A crash
The output shows some garbage value

Anything else you can think of is also possible.

Gavin Deane

Oct 24 '06 #8

Kouisawang wrote:
Stuart Redmann wrote:
Operator+ is already overloaded for pointers. Depending on the actual
type that is pointed to, operator+ for pointers will behave like this:

T* operator+ (T* BaseAddress, int Offset)
{
return (T*) int (BaseAddress) + sizeof (T) * Offset;
}
-----------------------------------------------------------------------------------------------------------------
So you mean all pointers already have overload "+" operation even
though
that pointer that doesn't belong to the predefined or primary
class/type?
Sorry again about noob question, I know just little about c++ and wanna
study more.
-----------------------------------------------------------------------------------------------------------------
<rearranged above>

What do you mean by "predefined or primary class/type"? Pointers are as
much built in and fundamental as types like int, double and bool.
Whenever you use the + operator to add an integer value to a pointer,
the behaviour is as described by the code above. And, because interger
types and pointer types are buil in to the language, there is no way
that you as the programmer can change the way the addition of an
integer to a pointer behaves, regarldess of whether that pointer type
happens to point to a built in type (e.g. int, double, bools etc.) or
points to some user defined (e.g. class) type. That behaviour is a
fundamental part of the language.

Gavin Deane

Oct 24 '06 #9

Gavin Deane wrote:
Kouisawang wrote:
Stuart Redmann wrote:
Operator+ is already overloaded for pointers. Depending on the actual
type that is pointed to, operator+ for pointers will behave like this:
>
T* operator+ (T* BaseAddress, int Offset)
{
return (T*) int (BaseAddress) + sizeof (T) * Offset;
}
-----------------------------------------------------------------------------------------------------------------
So you mean all pointers already have overload "+" operation even
though
that pointer that doesn't belong to the predefined or primary
class/type?
Sorry again about noob question, I know just little about c++ and wanna
study more.
-----------------------------------------------------------------------------------------------------------------

<rearranged above>

What do you mean by "predefined or primary class/type"? Pointers are as
much built in and fundamental as types like int, double and bool.
Whenever you use the + operator to add an integer value to a pointer,
the behaviour is as described by the code above. And, because interger
types and pointer types are buil in to the language, there is no way
that you as the programmer can change the way the addition of an
integer to a pointer behaves, regarldess of whether that pointer type
happens to point to a built in type (e.g. int, double, bools etc.) or
points to some user defined (e.g. class) type. That behaviour is a
fundamental part of the language.

Gavin Deane
My predefind class/type is your fundamental type. So I mean if we use a
pointer that is not of any fundamental type, will there already be its
overload function for us?
For example,

Fundamental type

int *i; // there will be the overload function of "+" for this object,
right

then what if

// myClass is the class that I have created
myClass *i; //will there be the overload function of "+" for this
object?

Thank you for your help :^)

Oct 24 '06 #10

Kouisawang wrote:
Gavin Deane wrote:
Kouisawang wrote:
Stuart Redmann wrote:
Operator+ is already overloaded for pointers. Depending on the actual
type that is pointed to, operator+ for pointers will behave like this:

T* operator+ (T* BaseAddress, int Offset)
{
return (T*) int (BaseAddress) + sizeof (T) * Offset;
}
What do you mean by "predefined or primary class/type"? Pointers are as
much built in and fundamental as types like int, double and bool.
Whenever you use the + operator to add an integer value to a pointer,
the behaviour is as described by the code above. And, because interger
types and pointer types are buil in to the language, there is no way
that you as the programmer can change the way the addition of an
integer to a pointer behaves, regarldess of whether that pointer type
happens to point to a built in type (e.g. int, double, bools etc.) or
points to some user defined (e.g. class) type. That behaviour is a
fundamental part of the language.

Gavin Deane

My predefind class/type is your fundamental type. So I mean if we use a
pointer that is not of any fundamental type, will there already be its
overload function for us?
For example,

Fundamental type

int *i; // there will be the overload function of "+" for this object,
right
There is no actual overloaded operator+ function for pointers. If you
add an int to the pointer i, all there is is behaviour mandated by the
language. The code posted by Stuart Redmann neatly describes that
mandated behaviour. But no function containing that (or equivalent)
code actually exists to be called. In the same way that

int a = 1;
int b = 2;
int c = a + b;

does not call any actual operator+ function for a pair of ints. The
behaviour is built in to the language and does not need to be defined
in a function somewhere.
then what if

// myClass is the class that I have created
myClass *i; //will there be the overload function of "+" for this
object?
No difference whatsoever. There is no actual overloaded operator+
function for pointers. If you add an int to the pointer i, exactly the
same behaviour is mandated by the language so Stuart Redmann's code is
an equally useful description of that behaviour. Note that his
description is based on a type pointer-to-T and makes no assumption
either way about whether T happens to be a built in type (e.g int) or a
user defined type (e.g myclass). That makes his description a sensible
one because as far as the language is concerned, with this question,
whether the type pointed to happens to be built in or user defined is
completely irrelevant.

Gavin Deane

Oct 24 '06 #11
Kouisawang wrote:
"C or C++ arrays are _always_ accessed starting from index zero up the
size of the array minus one."?

Can't we start accessing form any other positions in an array?
>>From the code above, I don't think there will be a problem if we change
from "for(int i=0;.....)"
to "for(int i=2, .....)". so not sure what do you mean by that.
I meant that if you want to access the first element of the array, you
have to use index zero. If you want to access the last element, you have
to use the index that equals the number of array elements minus one.
Note that C++ doesn't offer the possibility to define the index range
for an array, as this is allowed under Ada95 for example: The following
declaration is an Ada95 array declaration where the index starts from 50
and ends at 100 (so the array contains 51 Integers):
type Table is array(50 .. 100) of Integer;

(Unfortunately,) such facilities are not availale under C++ (that means
you have to use some templates to achive the same behaviour).

Regards,
Stuart
Oct 24 '06 #12
Kouisawang wrote:
My predefind class/type is your fundamental type. So I mean if we use a
pointer that is not of any fundamental type, will there already be its
overload function for us?
A pointer is a fundamental type, even if the things pointed are not.

--
Salu2
Oct 24 '06 #13
Thanks you all of you, appreciate it :^)

Oct 25 '06 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Morten Lind | last post: by
reply views Thread by scott_wu | last post: by
reply views Thread by Al Havrilla | last post: by
12 posts views Thread by Markus Ewald | last post: by
6 posts views Thread by nscbabu | last post: by
reply views Thread by =?Utf-8?B?REx1ZWNr?= | last post: by
reply views Thread by NPC403 | last post: by
1 post views Thread by fmendoza | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.