Thread: [?] what's the doese param in destroy(class* &i) mean?

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    9

    [?] what's the doese param in destroy(class* &i) mean?

    Code:
    void destroy(class* &i)
    {
          delete i;
          i = NULL;
    }
    
    class arr[3] = .....  .
    ./*construction for each element*/
    
    function(arr[0]);
    
    This is working.
    -------------version II-----------------
    Code:
    void destroy(class* i)
    {
          delete i;
          i = NULL;
    }
    
    class arr[3] = .....  .
    ./*construction for each element*/
    destroy(arr[0]);
    
    This is n't working (Runngtime error);
    Why? what does magic "&" do?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The &, in this case, means that you are passing by reference, which allows the function, destroy in this case, to modify the value of i.

    However, I'm a bit suspect to your code - I don't think either should work the way they are, as you are deleting a static array - it may be that it's not actually working in either case, but it APPEARS to work in the first case due to some spurios side-effect. You should NEVER delete something that wasn't created by new.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Code:
    class arr[3] = .....  .
    ./*construction for each element*/
    destroy(arr[0]);
    To do this, you'd need to have an array of pointers allocated with new:

    Code:
    Class* arr[3] = { new Class, new Class, new Class };
    Code:
    void destroy(class* i)
    {
          delete i;
          i = NULL;
    }
    Here setting i to NULL serves no purpose, since the pointer i is a local variable and goes out of scope anyway (the caller's pointer will keep the same value).

    Code:
    void destroy(class* &i)
    Here the pointer is passed by reference, hence changes to i in destroy will affect the value of the pointer passed in (the caller's pointer will be NULL after this call).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    9
    thanks.
    sorry for not clear about the code. the class arr[3] is created by "new" .

    arry is a an array of pointer to the Class;
    arr[1] is the pointer to Class;which is initialized by new Class(.....);

    so doesn't "delete arr[1]" delete the Class object holding by arr[1]?
    Last edited by martinuk; 01-16-2009 at 10:50 AM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Would you be able to post the ACTUAL code, as the devil is in the detail here.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    9
    Code:
    //--------Version 1-------------
    //button is a class and  array elements in b are created by new Button(....)
    Button* b[3];
    
    void MainWindow::bh0(){
        std::printf("button_0 pressed\n");
        destoryButton(b[1]);
    }
    void MainWindow::destoryButton(Button* b)
    {
        if (b!=NULL){
            delete b;
            b = NULL;
        }
    }
    //------Version 2------------
    //button is a class and  array elements in b are created by new Button(....)
    Button* b[3];
    
    void MainWindow::bh0(){
        std::printf("button_0 pressed\n");
        if(b[1]!=NULL){
                  delete b[1];
                  b[1] =NULL;
            }
    }
    Both compiled ok, but the Ver 1 has run time error.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by martinuk
    Both compiled ok, but the Ver 1 has run time error.
    Ah, but the error is probably produced by code that you did not show.

    The problem is that since destoryButton takes its argument by value, b = NULL merely acts on the local copy of the pointer passed to the function. Consequently, in the caller, the pointer continues to point to the destroyed Button object. If later code performs a check for a null pointer before using the object pointed to, the check will conclude that the pointer is not a null pointer, leading to the use of the destroyed object, resulting in undefined behaviour that can be manifested in a run time error.

    The solution is to change destoryButton to take its argument by reference. Actually, there's more: the check for NULL is unnecessary because it is safe to use delete on a null pointer. If you find yourself frequently writing code that uses delete followed by setting the pointer to a null pointer constant, consider writing a function template to do it for you, as described by Stroutrup's answer to Why doesn't delete zero out its operand?

    You would then write:
    Code:
    void MainWindow::destoryButton(Button*& b)
    {
        destroy(b);
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Here is good advice to avoid confusion. Everything in C and C++ is passed by value. Everything. That means the value in the variable you pass is copied, a new variable is created, a local variable to the function, and is assigned the value from the variable you copy.
    So if a new copy is made, how can we modify a variable in another function?
    The easiest way, in C++, is simply to declare it a reference. Simplistically, we might say that the local "variable" in the function is an alias for the original variable that you pass, so it is modified instead of a local copy.

    I hope that explains what happens and why.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. passing an array created with malloc as a param
    By mariano_donati in forum C Programming
    Replies: 12
    Last Post: 02-20-2008, 12:26 PM
  2. NAQ: Everything you never wanted to know about CPP
    By evildave in forum C Programming
    Replies: 21
    Last Post: 12-12-2005, 10:56 AM