Pointer changed unexpectedly.

Discussion in 'C++' started by Denis Remezov, May 12, 2004.

  1. 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!=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
    Denis Remezov, May 12, 2004
    #1
    1. Advertising

  2. Denis Remezov

    John Guest

    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
    John, May 12, 2004
    #2
    1. Advertising

  3. Denis Remezov

    John Guest

    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 <> wrote in message news:<>...
    > 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!=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
    John, May 13, 2004
    #3
  4. 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
    Karl Heinz Buchegger, May 13, 2004
    #4
  5. Denis Remezov

    John Guest

    Karl Heinz Buchegger <> wrote in message news:<>...
    > 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?

    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.
    John, May 14, 2004
    #5
  6. John wrote:
    >
    > Karl Heinz Buchegger <> wrote in message news:<>...
    > > 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?
    >


    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
    Denis Remezov, May 15, 2004
    #6
  7. John wrote:
    >
    > Karl Heinz Buchegger <> wrote in message news:<>...
    > > 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.

    > > 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
    Karl Heinz Buchegger, May 17, 2004
    #7
  8. Denis Remezov

    John Guest

    Karl Heinz Buchegger <> wrote in message news:<>...
    > John wrote:
    > >
    > > Karl Heinz Buchegger <> wrote in message news:<>...
    > > > 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
    John, May 18, 2004
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Art Werschulz
    Replies:
    0
    Views:
    657
    Art Werschulz
    Dec 3, 2003
  2. Dave Stockton

    aspnet_wp.exe stopped unexpectedly

    Dave Stockton, Jul 9, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    405
    Dave Stockton
    Jul 9, 2003
  3. Keith
    Replies:
    0
    Views:
    374
    Keith
    Aug 19, 2003
  4. Replies:
    1
    Views:
    681
    Rosanne
    Oct 11, 2005
  5. mxbrunet
    Replies:
    1
    Views:
    210
Loading...

Share This Page