Board index » cppbuilder » Access violation with 'new[]'

Access violation with 'new[]'


2004-01-20 05:23:30 PM
cppbuilder31
I have an area of my code that calls 'new[]' which works fine,
except in certain situations I get an access violation. I would
post the code, however I don't think the use of 'new[]' itself is
the problem. This occurs in a class function, and I think it
might be being called against a bad pointer, but I am not sure.
Can anyone tell me what kind of thing I should look for to find
the problem (I am already looking for bad casts)?
I have inserted 'std::cout' with test output to try to trace it
back to the source (by looking at the last output line before the
violation to see what called the function) as follows:
struct A
{
void F1()
{
std::cout << "F1 Start\n";
//Do stuff
std::cout << "F1 End\n";
}
};
struct B
{
void F2()
{
std::cout << "F2 Start\n";
DATA.F1();
//Do stuff
std::cout << "F2 End\n";
}
private:
A DATA;
};
int main()
{
B ONE;
std::cout << "1\n";
ONE.F2();
std::cout << "2\n";
B *TWO = &ONE;
std::cout << "3\n";
TWO->F2();
std::cout << "4\n";
}
however the source is not consistent, and can be effected by
adding code to a completely unrelated area (such as adding a
'std::cin.get()' in main()).
Something that has been happening also (that might be related):
when I use 'std::cin.get()', sometimes I will press enter too
quickly, and then the entire program will scroll past any further
input all the way to the end. Sometimes this ends in an access
violation.
Any help is greatly appreciated. Thanks
ta0kira
 
 

Re:Access violation with 'new[]'

"ta0kira" < XXXX@XXXXX.COM >writes:
Quote
I have inserted 'std::cout' with test output to try to trace it
back to the source (by looking at the last output line before the
violation to see what called the function) as follows:
[snip]
The program you posted is correct, provided <iostream>and <ostream>are
#included. It should not cause an access violation; if it does, there may
be something wrong with the settings you are using for compiling and linking.
Quote
however the source is not consistent, and can be effected by
adding code to a completely unrelated area (such as adding a
'std::cin.get()' in main()).

Something that has been happening also (that might be related):
when I use 'std::cin.get()', sometimes I will press enter too
quickly, and then the entire program will scroll past any further
input all the way to the end. Sometimes this ends in an access
violation.
It seems that you are using std::cin in an inappropriate way. It's difficult
to say anything more specific.
 

Re:Access violation with 'new[]'

Quote
The program you posted is correct, provided <iostream>and <ostream>are
#included. It should not cause an access violation; if it does, there may
be something wrong with the settings you are using for compiling and linking.
That code was just an example of the method I am using to trace
the function call back to its origin.
I know of 2 ways that 'new[]' can cause an access violation:
1) If the value of the size_t is <= 0, which I check for before
the 'new[]' operation that gets the violation
2) If the resulting pointer is stored in a variable that does
not exist:
(not compiled)
struct A
{
A() : DATA(NULL) {}
void NEW(unsigned int sSize)
{
delete[] DATA;
DATA = new int[sSize];
}
private:
int *DATA;
};
int main()
{
int ONE = 10; //Create random object
A *TWO = (A*) &ONE; //Bad pointer cast
TWO->NEW(10); //Call against bad pointer
}
Of course, in this case the access violation should occur on the
line with 'delete[]', however if that were not there I am pretty
sure it would still happen on the line with 'new[]'. I think
this might be the problem, only the variable the result of 'new[]'
is stored in is a local one in the error code.
Is there any other circumstance that 'new[]' could cause an
access violation?
Quote
It seems that you are using std::cin in an inappropriate way. It's difficult
to say anything more specific.
I use 'std::cin' only in 3 ways:
1) 'std::cin>>/*variable*/;' where 'variable' is a funamental
type; usually char*, int, or double.
2)
char OPTION;
int VALUE;
std::cin.get(OPTION);
VALUE = OPTION - '0';
case (VALUE)
{
//...
};
3) 'std::cin.get();' in places I want the program to stop and
wait for 'enter'. If by chance a character is typed before
'enter' is, the next 'std::cin.get();' is skipped over. Since
this happens, that leads me to believe that maybe the keyboard
buffer gets under-run somehow. This has given me access
violations even on lines such as 'while (/*bool var*/)'. In the
case of violations caused by 'std::cin.get();', the line of code
with the violation is inconsistent, but the violation in the
function with 'new[]' is something new that came up in otherwise
functional code. The code functioned perfectly before, and I
had tested it in as many situations as possible (it is not the
code with the 'new[]' statement; I am sure of it), so I am now
looking for somewhere in my other code that calls that function
against a bad pointer. At this point the program crashes at the
'new[]' every time, at the same point in 'main()'.
ta0kira
 

{smallsort}

Re:Access violation with 'new[]'

"ta0kira" < XXXX@XXXXX.COM >writes:
Quote
Is there any other circumstance that 'new[]' could cause an
access violation?
As a consequence of something gone bad before. If your program had
undefined behavior before the call to new [], it can well have caused a
mess in the dynamic memory manager.
Quote
I use 'std::cin' only in 3 ways:

1) 'std::cin>>/*variable*/;' where 'variable' is a funamental
type; usually char*, int, or double.

2)
char OPTION;
int VALUE;

std::cin.get(OPTION);
VALUE = OPTION - '0';

case (VALUE)
{
//...
};
In both cases, your program will have undefined behavior if the input
operation fails.
Quote
3) 'std::cin.get();' in places I want the program to stop and
wait for 'enter'. If by chance a character is typed before
'enter' is, the next 'std::cin.get();' is skipped over. Since
this happens, that leads me to believe that maybe the keyboard
buffer gets under-run somehow. This has given me access
violations even on lines such as 'while (/*bool var*/)'.
Access violations at random places are usually indications of a problem
(i.e. undefined behavior) previously in the program flow.
 

Re:Access violation with 'new[]'

XXXX@XXXXX.COM (Thomas Maeder [TeamB]) wrote:
Quote
[...] Access violations at random places are usually
indications of a problem (i.e. undefined behavior)
previously in the program flow.
I disagree. My experiance tells me that it's ALWAYS why my
current project {*word*99}ped out on me <g>.
~ JD
 

Re:Access violation with 'new[]'

Quote
In both cases, your program will have undefined behavior if the input
operation fails.
So would initializing the input variables correct that? :
char OPTION = '/0';
//Could I also use 'char OPTION();'?
std::cin.get(OPTION);
Quote
Access violations at random places are usually indications of a problem
(i.e. undefined behavior) previously in the program flow.
If that is the case, the undefined behavior occurs as follows:
std::cin.get(); //Line 1
char *TEXT; //Line 2
std::cin>>TEXT; //Line 3
if (TEXT[0] != '\0') {}; //Line 4
At line 1, if you type in something such as 'X [Enter]', then
the extra character 'X' is inserted into 'TEXT' in line 3.
The access violation occurs when enter is pressed too quickly
(not even sure how this is possible, but I can prevent the error
by using a firm, deliberate key press) then I think line 1 is
given something other than acceptable, making that line have
undefined behavior, giving me an access violation at line 4.
The problem with the access violation on a 'new[]' operation has
happened before in a different class, and the way I 'corrected'
it was to change my implementation of 'std::cin' in my actual
implementation header for my class debugging program. In either
case, the pointer is 'NULL' before the 'new[]', so if it fails
the pointer is not undefined. In the end, it has always been my
use of 'std::cin' to give me random access violations, and new
problems are generally stopped (not necessarily corrected) by
'undoing' changes I made to my use of 'std::cin'.
So what is the best way to ensure use of 'std::cin' is NEVER
undefined? Thanks
ta0kira
 

Re:Access violation with 'new[]'

ta0kira wrote:
Quote
So would initializing the input variables correct that? :
You should check the stream state:
if(!std::cin)
{
//failure
}
Quote

char OPTION = '/0';
//Could I also use 'char OPTION();'?
'char OPTION();' will declare a function named OPTION that returns a
char. Instead you could write it as 'char OPTION = char();'
Quote
If that is the case, the undefined behavior occurs as follows:

std::cin.get(); //Line 1
This extracts a character, which is fine.
Quote
char *TEXT; //Line 2
You define an uninitialized pointer that points to some random place in
memory.
Quote
std::cin>>TEXT; //Line 3
You extracts characters and writes them to where TEXT is pointing, which
is some random place. You have now hit undefined behavior.
Instead of a char* use std::string:
std::string TEXT;
std::cin>>TEXT;
if(!TEXT.empty()) {}
Ivan Johansen
 

Re:Access violation with 'new[]'

Quote
>char *TEXT; //Line 2

You define an uninitialized pointer that points to some random place in
memory.
Sorry, I usually use
char TEXT[/*size*/];
I will try 'istream::operator !'. If I use code such as:
std::cin.get(); //Wait for [Enter]
if (!std::cin) std::cin.clear(); //Will this stop scrolling?
char INPUT[32];
std::cin>>INPUT; //Get input
if (INPUT[0] != '\0') {} //Process
should that stop the program from scrolling past inputs if an
input error occurs? Thanks
ta0kira
 

Re:Access violation with 'new[]'

"ta0kira" < XXXX@XXXXX.COM >writes:
Quote
So would initializing the input variables correct that? :

char OPTION = '/0';
This is a multi-character literal. Multi-character literals are very strange
and non-portable beasts.
I assume you meant '\0'.
And yes, this would help. Better yet, check the return value of the input
operation and leave the variable alone if it couldn't be read.
 

Re:Access violation with 'new[]'

"ta0kira" < XXXX@XXXXX.COM >writes:
Quote
I will try 'istream::operator !'. If I use code such as:

std::cin.get(); //Wait for [Enter]

if (!std::cin) std::cin.clear(); //Will this stop scrolling?
Scrolling is the least of your problems. The undefined behavior is your
problem. And I don't see the above line how calling clear() could prevent
it from happening.
Quote

char INPUT[32];
std::cin>>INPUT; //Get input
This isn't much better since, depending on the current width of std::cin,
input can overflow the array.
Better do
std::string line;
if (getline(std::cin,line))
; // process line
else
; // input failed
 

Re:Access violation with 'new[]'

Quote
Scrolling is the least of your problems. The undefined behavior is your
problem. And I don't see the above line how calling clear() could prevent
it from happening.
So 'undefined' happens when you do not initialize, correct?
What else causes undefined behavior?
Quote
std::string line;
if (getline(std::cin,line))
; // process line
else
; // input failed
Thanks.
ta0kira
 

Re:Access violation with 'new[]'

Quote
I assume you meant '\0'.
Yes.
Quote
And yes, this would help. Better yet, check the return value of the input
operation and leave the variable alone if it couldn't be read.
So, maybe:
std::string INPUT;
if (!(std::cin>>INPUT))
{
//fail
}
else
{
//process
};
Thanks
ta0kira
 

Re:Access violation with 'new[]'

"ta0kira" < XXXX@XXXXX.COM >writes:
[quotes rearranged by tm]
Quote
>Scrolling is the least of your problems. The undefined behavior is your
>problem. And I don't see the above line how calling clear() could prevent
>it from happening.

So 'undefined' happens when you do not initialize, correct?
No. Only if you perfom a "lvalue to rvalue" conversion (i.e. you read a
variable) that wasn't initialized.
I remember Jack Klein (aka "Mr. C and C++ FAQ") post in one of the Borland
newsgroups that you can get away with reading an uninitialized variable of
type unsigned char; but even if this is true (which is very likely since
IMHO, he knows more about these things than anybody else posting here), I
consider it bad practice to rely on this in general.
Quote
>std::string line;
>if (getline(std::cin,line))
>; // process line
>else
>; // input failed
Note that "simplifying" this to
std::string line;
getline(std::cin,line);
// process line
has defined behavior, since line was initialized using std::string's default
constructor. OTOH, if you don't check for the success of getline(), you don't
know if an empty line was read or if input failed.
Quote
What else causes undefined behavior?
Everything that the ISO C++ Standard explicity states as undefined behavior,
and everything it doesn't define at all.
 

Re:Access violation with 'new[]'

"ta0kira" < XXXX@XXXXX.COM >writes:
Quote
So, maybe:

std::string INPUT;
if (!(std::cin>>INPUT))
{
//fail
}
else
{
//process
};
Yes.
I prefer simple if conditions, so I'd reverse the two cases, but that's
personal taste.
I'd also not write the ';' at the end. It is superfluous, but it doesn't
hurt.
 

Re:Access violation with 'new[]'

Quote
>if (!(std::cin>>INPUT))
I prefer simple if conditions, so I'd reverse the two cases,
So if I take out the '!()', I take it 'operator void*' is then
evaluated, giving the same result as what I have above? The way
I have it, 'operator !' is called, giving the state of the
stream. I think you were thinking I was inverting the result of
the operation.
ta0kira