Pointer changed unexpectedly.

D

Denis Remezov

John said:
Hi all,

In my code, pointer changes unexpectedly. Below is the description of
the problem:

void class1::function1(){
class2 *r1;
class2 *rr[10];

r1 = new class2;

printf("r1_1: %d\n", r1);

function2(rr);

for(int i=0; rr!=NULL; i++){
printf("r1_2: %d\n", r1);
......
}

printf("r1_3: %d\n", r1);

}

The above code shows the structure of my code.
I define two classes.
The function2() is used to bring back an array of pointers, rr[], of
which the last element is NULL to indicate the end of the array.

There are 100 objects of class1. The strange thing is that at a
particular time when one object executes function1(), I get the
following output:
r1_1: some value, like 3563246.
r1_2: 0
r1_2: 0
r1_2: 0
r1_2: 0
r1_2: 0
r1_3: 0

But the pointer r1 should not change. r1_1, r1_2 and r1_3 should be
the same non-zero value.

This problem only happens once, during the execution of the code.

What is the problem?


Impossible to say for sure without seeing function2().
The obvious guess is that function2(rr) overwrites the content of r1
(the pointer) when it initialises the rr array (it's very easy if r1
and rr live on the stack, r1 immediately following or preceding the
rr array). You are lucky you didn't overwrite function1's return
address. Look for any indicies being out of range while accessing
rr in function2().

How does function2() know how many elements there are in the array?
It shouldn't just rely on a magic number. If you insist on using an
array, at least make its size known explicitly, it will be easier to
avoid problems like this that way. Better yet, use an std::vector
instead and avoid tricks like storing a NULL to indicate the end
of a sequence.

Denis
 
J

John

Hi all,

In my code, pointer changes unexpectedly. Below is the description of
the problem:

void class1::function1(){
class2 *r1;
class2 *rr[10];

r1 = new class2;

printf("r1_1: %d\n", r1);

function2(rr);

for(int i=0; rr!=NULL; i++){
printf("r1_2: %d\n", r1);
......
}

printf("r1_3: %d\n", r1);

}

The above code shows the structure of my code.
I define two classes.
The function2() is used to bring back an array of pointers, rr[], of
which the last element is NULL to indicate the end of the array.

There are 100 objects of class1. The strange thing is that at a
particular time when one object executes function1(), I get the
following output:
r1_1: some value, like 3563246.
r1_2: 0
r1_2: 0
r1_2: 0
r1_2: 0
r1_2: 0
r1_3: 0

But the pointer r1 should not change. r1_1, r1_2 and r1_3 should be
the same non-zero value.

This problem only happens once, during the execution of the code.

What is the problem?

I hope I have clearly explain the problem.

Thanks a lot.

John
 
J

John

Hi Denis,

Thanks a lot. You are right. I find that function2() tries to write 11
elements in to array rr.
If I define the size of array rr in function2(), e.g., I put "class2
*rr[10];" in function2(), but function2() still tries to write 11
elements into array rr, what will happen?
By the way, if function1's return address is overwritten, what will
happen? segmentation fault?

John

Denis Remezov said:
John said:
Hi all,

In my code, pointer changes unexpectedly. Below is the description of
the problem:

void class1::function1(){
class2 *r1;
class2 *rr[10];

r1 = new class2;

printf("r1_1: %d\n", r1);

function2(rr);

for(int i=0; rr!=NULL; i++){
printf("r1_2: %d\n", r1);
......
}

printf("r1_3: %d\n", r1);

}

The above code shows the structure of my code.
I define two classes.
The function2() is used to bring back an array of pointers, rr[], of
which the last element is NULL to indicate the end of the array.

There are 100 objects of class1. The strange thing is that at a
particular time when one object executes function1(), I get the
following output:
r1_1: some value, like 3563246.
r1_2: 0
r1_2: 0
r1_2: 0
r1_2: 0
r1_2: 0
r1_3: 0

But the pointer r1 should not change. r1_1, r1_2 and r1_3 should be
the same non-zero value.

This problem only happens once, during the execution of the code.

What is the problem?


Impossible to say for sure without seeing function2().
The obvious guess is that function2(rr) overwrites the content of r1
(the pointer) when it initialises the rr array (it's very easy if r1
and rr live on the stack, r1 immediately following or preceding the
rr array). You are lucky you didn't overwrite function1's return
address. Look for any indicies being out of range while accessing
rr in function2().

How does function2() know how many elements there are in the array?
It shouldn't just rely on a magic number. If you insist on using an
array, at least make its size known explicitly, it will be easier to
avoid problems like this that way. Better yet, use an std::vector
instead and avoid tricks like storing a NULL to indicate the end
of a sequence.

Denis
 
K

Karl Heinz Buchegger

John said:
Hi Denis,

Thanks a lot. You are right. I find that function2() tries to write 11
elements in to array rr.
If I define the size of array rr in function2(), e.g., I put "class2
*rr[10];" in function2(), but function2() still tries to write 11
elements into array rr, what will happen?

Nobody knows. It is undefind.
Anything can happen.
By the way, if function1's return address is overwritten, what will
happen? segmentation fault?

Same as above.

But a possible scenary would be:
You overwrite the return address with some bytes
which happen to be a valid address in your system.
Unfortunately this is the address of the low level
BIOS function which formats your hard drive :)
 
J

John

Karl Heinz Buchegger said:
John said:
Hi Denis,

Thanks a lot. You are right. I find that function2() tries to write 11
elements in to array rr.
If I define the size of array rr in function2(), e.g., I put "class2
*rr[10];" in function2(), but function2() still tries to write 11
elements into array rr, what will happen?

Nobody knows. It is undefind.
Anything can happen.

To prevent it, I add a condition in function2() to check the index, like,
if(i < 10) rr = r0;
else std::cout<<"overflow"<<endl;

Is there a better way to do it?

Thanks.
Same as above.

But a possible scenary would be:
You overwrite the return address with some bytes
which happen to be a valid address in your system.
Unfortunately this is the address of the low level
BIOS function which formats your hard drive :)

oh, like a virus.
 
D

Denis Remezov

John said:
Karl Heinz Buchegger said:
John said:
Hi Denis,

Thanks a lot. You are right. I find that function2() tries to write 11
elements in to array rr.
If I define the size of array rr in function2(), e.g., I put "class2
*rr[10];" in function2(), but function2() still tries to write 11
elements into array rr, what will happen?

Nobody knows. It is undefind.
Anything can happen.

To prevent it, I add a condition in function2() to check the index, like,
if(i < 10) rr = r0;
else std::cout<<"overflow"<<endl;

Is there a better way to do it?


There can be different kinds of checks.

Some tests are for programming errors within your control, and so should
always pass (i.e. if they don't it's a fixable bug). For these, perhaps the
simplest thing to do is to write
assert(i < element_count); //where element_count happens to be 10
(Look it up in the documentation, the details are important).

Some other tests are for conditions that cannot be expected to always be true
in a working function/unit/program.
For graceful handling of errors beyond your control exception classes can
sometimes be useful (but don't use them unless you know you should; returning
an error from a function is very often a better choice).

These are just incomplete superficial pointers, you might want to look for a
systematic treatment of error handling.

Denis
 
K

Karl Heinz Buchegger

John said:
Karl Heinz Buchegger said:
John said:
Hi Denis,

Thanks a lot. You are right. I find that function2() tries to write 11
elements in to array rr.
If I define the size of array rr in function2(), e.g., I put "class2
*rr[10];" in function2(), but function2() still tries to write 11
elements into array rr, what will happen?

Nobody knows. It is undefind.
Anything can happen.

To prevent it, I add a condition in function2() to check the index, like,
if(i < 10) rr = r0;
else std::cout<<"overflow"<<endl;

Is there a better way to do it?


It depends on what function2 does.

If function2 looks something like this:

for( int i = 0; i <= 10; ++i )
rr = r0;

Then the simplest thing is to make the for loop correct and
follow the usual C++ idiom

for( int i = 0; i < 10; ++i )
rr = r0;

But there are zillion other possible scenarios so a general
answer cannot be given. But it certainly would be a good idea
to pass the array size into that function, to make it independent of
that magical number 10.
oh, like a virus.

Not necessarily. I harmful virus is programmed by a criminal
by intention.
 
J

John

Karl Heinz Buchegger said:
John said:
Karl Heinz Buchegger said:
John wrote:

Hi Denis,

Thanks a lot. You are right. I find that function2() tries to write 11
elements in to array rr.
If I define the size of array rr in function2(), e.g., I put "class2
*rr[10];" in function2(), but function2() still tries to write 11
elements into array rr, what will happen?

Nobody knows. It is undefind.
Anything can happen.

To prevent it, I add a condition in function2() to check the index, like,
if(i < 10) rr = r0;
else std::cout<<"overflow"<<endl;

Is there a better way to do it?


It depends on what function2 does.

If function2 looks something like this:

for( int i = 0; i <= 10; ++i )
rr = r0;

Then the simplest thing is to make the for loop correct and
follow the usual C++ idiom

for( int i = 0; i < 10; ++i )
rr = r0;

But there are zillion other possible scenarios so a general
answer cannot be given. But it certainly would be a good idea
to pass the array size into that function, to make it independent of
that magical number 10.


Thanks a lot.
I use function2() to bring back pointers to object from a linked list
of object.
If an element of the linked list satisfies a condition,like x->aa >=
10 (aa is data member of object), x is put into the array rr[]. I use
NULL to mark the end of the array rr[]. I do not know how many
elements the linked list has. I estimate the number is less than 10.
I have increased the size of the array rr[] to be 30. From output I
find that there are less than 20 elements written in the the array
rr[]. But unfortunately, another pointer still change to NULL,
although it is not expected to be changed.

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top