By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,797 Members | 1,848 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,797 IT Pros & Developers. It's quick & easy.

Pointer changed unexpectedly.

P: n/a
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[i]!=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
Jul 22 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
John wrote:

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[i]!=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
Jul 22 '05 #2

P: n/a
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 <RE*********************@yahoo.removethis.ca> wrote in message news:<40***************@yahoo.removethis.ca>...
John wrote:

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[i]!=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

Jul 22 '05 #3

P: n/a
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.
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 :-)

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #4

P: n/a
Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<40***************@gascad.at>...
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[i] = r0;
else std::cout<<"overflow"<<endl;

Is there a better way to do it?

Thanks.
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 :-)


oh, like a virus.
Jul 22 '05 #5

P: n/a
John wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<40***************@gascad.at>...
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[i] = 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
Jul 22 '05 #6

P: n/a
John wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<40***************@gascad.at>...
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[i] = 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[i] = 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[i] = 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.
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.


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

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #7

P: n/a
Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<40***************@gascad.at>...
John wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote in message news:<40***************@gascad.at>...
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[i] = 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[i] = 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[i] = 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
Jul 22 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.