warning: taking address of temporary

Discussion in 'C++' started by daniell@digitalfiling.com, May 8, 2007.

  1. Guest

    /*
    Triangle.cpp
    */

    // Use a pure virtual function.

    #include <iostream>
    #include <cstring>
    using namespace std;

    // A class for two-dimensional objects.
    class TwoDShape {
    // these are private
    double width;
    double height;

    // add a name field
    char name[20];
    public:

    // Default constructor.
    TwoDShape() {
    width = height = 0.0;
    strcpy(name, "unknown");
    }

    // Constructor for TwoDShape.
    TwoDShape(double w, double h, char *n) {
    width = w;
    height = h;
    strcpy(name, n);
    }

    // Construct object with equal width and height.
    TwoDShape(double x, char *n) {
    width = height = x;
    strcpy(name, n);
    }

    void showDim() {
    cout << "Width and height are " << width << " and " << height <<
    "\n";
    }

    // accessor functions
    double getWidth() { return width; }
    double getHeight() { return height; }
    void setWidth(double w) { width = w; }
    void setHeight(double h) { height = h; }
    char *getName() { return name; }

    // area() is now a pure virtual function
    virtual double area() = 0;

    };

    // Triangle is derived from TwoDShape.
    class Triangle : public TwoDShape {
    char style[20]; //now private
    public:

    /* A default constructor. This automatically invokes
    the default constructor of TwoDShape. */
    Triangle() {
    strcpy(style, "unknown");
    }

    // Constructor with three parameters.
    Triangle(char *str, double w, double h)
    : TwoDShape(w, h, "triangle") {
    strcpy(style, str);
    }

    // Construct an isosceles triangle.
    Triangle(double x) : TwoDShape(x, x, "triangle") {
    strcpy(style, "isosceles");
    }

    // This now overrides area() declared in TwoDShape.
    double area() {
    return getWidth() * getHeight() / 2;
    }

    void showStyle() {
    cout << "Triangle is " << style << "\n";
    }
    };

    int main() {
    // declare an array of pointers to TwoDShape objects.
    TwoDShape *shapes[4];

    shapes[0] = &Triangle("right", 8.0, 12.0);
    shapes[1] = &Triangle(3.0);
    shapes[2] = &Triangle(4.0);
    shapes[3] = &Triangle(7.0);

    for(int i=0; i < 2; i++) {
    cout << "object is " <<
    shapes->getName() << "\n";

    cout << "Area is " <<
    shapes->area() << "\n";

    cout << "\n";
    }

    return 0;
    }

    Hi, I'm a beginning programmer. Above is the code that is giving me
    the error. I have talked with a professor about this issue. The
    error happens on the lines beginning "shapes[0] = ... "

    The professor says, because Triangle was created without a variable
    they are temporary objects. Which means they will be destroyed and
    the pointer becomes a dangling pointer.

    I edited the code and just created the objects and gave them a
    variable to be stored in. i.e. "Triangle t1("right", 4, 5);" Then I
    just do "shapes[0] = &t1;" When I recompile, I get no warnings and it
    runs as expected.

    My question: Is there a way so that the temporary objects are not
    destroyed? Seems like a waste of memory to create a variable outside
    of the array that will always be referenced through the array.
     
    , May 8, 2007
    #1
    1. Advertising

  2. Guest

    On May 8, 10:58 am, wrote:

    <snip>

    > My question: Is there a way so that the temporary objects are not
    > destroyed? Seems like a waste of memory to create a variable outside
    > of the array that will always be referenced through the array.


    For the purpose of this example, create the Triangles with new.

    shapes[0] = new Triangle(...);

    shapes[0] now holds the address of the created Triangle.

    If you're writing an application that does something like this, you
    might want to look at std::vector and boost::shared_ptr.
     
    , May 8, 2007
    #2
    1. Advertising

  3. On 2007-05-08 16:58, wrote:
    > /*
    > Triangle.cpp
    > */
    >
    > // Use a pure virtual function.
    >
    > #include <iostream>
    > #include <cstring>
    > using namespace std;
    >
    > // A class for two-dimensional objects.
    > class TwoDShape {
    > // these are private
    > double width;
    > double height;
    >
    > // add a name field
    > char name[20];
    > public:
    >
    > // Default constructor.
    > TwoDShape() {
    > width = height = 0.0;
    > strcpy(name, "unknown");
    > }
    >
    > // Constructor for TwoDShape.
    > TwoDShape(double w, double h, char *n) {
    > width = w;
    > height = h;
    > strcpy(name, n);
    > }
    >
    > // Construct object with equal width and height.
    > TwoDShape(double x, char *n) {
    > width = height = x;
    > strcpy(name, n);
    > }
    >
    > void showDim() {
    > cout << "Width and height are " << width << " and " << height <<
    > "\n";
    > }
    >
    > // accessor functions
    > double getWidth() { return width; }
    > double getHeight() { return height; }
    > void setWidth(double w) { width = w; }
    > void setHeight(double h) { height = h; }
    > char *getName() { return name; }
    >
    > // area() is now a pure virtual function
    > virtual double area() = 0;
    >
    > };
    >
    > // Triangle is derived from TwoDShape.
    > class Triangle : public TwoDShape {
    > char style[20]; //now private
    > public:
    >
    > /* A default constructor. This automatically invokes
    > the default constructor of TwoDShape. */
    > Triangle() {
    > strcpy(style, "unknown");
    > }
    >
    > // Constructor with three parameters.
    > Triangle(char *str, double w, double h)
    > : TwoDShape(w, h, "triangle") {
    > strcpy(style, str);
    > }
    >
    > // Construct an isosceles triangle.
    > Triangle(double x) : TwoDShape(x, x, "triangle") {
    > strcpy(style, "isosceles");
    > }
    >
    > // This now overrides area() declared in TwoDShape.
    > double area() {
    > return getWidth() * getHeight() / 2;
    > }
    >
    > void showStyle() {
    > cout << "Triangle is " << style << "\n";
    > }
    > };
    >
    > int main() {
    > // declare an array of pointers to TwoDShape objects.
    > TwoDShape *shapes[4];
    >
    > shapes[0] = &Triangle("right", 8.0, 12.0);
    > shapes[1] = &Triangle(3.0);
    > shapes[2] = &Triangle(4.0);
    > shapes[3] = &Triangle(7.0);
    >
    > for(int i=0; i < 2; i++) {
    > cout << "object is " <<
    > shapes->getName() << "\n";
    >
    > cout << "Area is " <<
    > shapes->area() << "\n";
    >
    > cout << "\n";
    > }
    >
    > return 0;
    > }
    >
    > Hi, I'm a beginning programmer. Above is the code that is giving me
    > the error. I have talked with a professor about this issue. The
    > error happens on the lines beginning "shapes[0] = ... "
    >
    > The professor says, because Triangle was created without a variable
    > they are temporary objects. Which means they will be destroyed and
    > the pointer becomes a dangling pointer.
    >
    > I edited the code and just created the objects and gave them a
    > variable to be stored in. i.e. "Triangle t1("right", 4, 5);" Then I
    > just do "shapes[0] = &t1;" When I recompile, I get no warnings and it
    > runs as expected.
    >
    > My question: Is there a way so that the temporary objects are not
    > destroyed? Seems like a waste of memory to create a variable outside
    > of the array that will always be referenced through the array.


    The simplest (as in requires the least change in the code) way to do
    this is to use new to allocate the Triangles on the heap (dynamic
    memory). Objects created with new will continue to exist until they are
    explicitly deleted (even if you no longer have a pointer or reference to
    them!). This means that when you no longer need an object created with
    new you must delete them or your program will use up all memory.

    To create a Triangle using new do this:

    shapes[0] = new Triangle("right", 8.0, 12.0);

    And when you are done with it you use delete to delete them:

    delete shapes[0];

    I guess that you have not discusses dynamic memory in class, beware that
    there are some problems with it if you are not careful and it is
    therefore generally a good idea not to use it, but sometimes you have to.

    --
    Erik Wikström
     
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, May 8, 2007
    #3
  4. Guest

    On May 8, 11:28 am, Erik Wikström <> wrote:
    > On 2007-05-08 16:58, wrote:
    >
    >
    >
    >
    >
    > > /*
    > > Triangle.cpp
    > > */

    >
    > > // Use a pure virtual function.

    >
    > > #include <iostream>
    > > #include <cstring>
    > > using namespace std;

    >
    > > // A class for two-dimensional objects.
    > > class TwoDShape {
    > > // these are private
    > > double width;
    > > double height;

    >
    > > // add a name field
    > > char name[20];
    > > public:

    >
    > > // Default constructor.
    > > TwoDShape() {
    > > width = height = 0.0;
    > > strcpy(name, "unknown");
    > > }

    >
    > > // Constructor for TwoDShape.
    > > TwoDShape(double w, double h, char *n) {
    > > width = w;
    > > height = h;
    > > strcpy(name, n);
    > > }

    >
    > > // Construct object with equal width and height.
    > > TwoDShape(double x, char *n) {
    > > width = height = x;
    > > strcpy(name, n);
    > > }

    >
    > > void showDim() {
    > > cout << "Width and height are " << width << " and " << height <<
    > > "\n";
    > > }

    >
    > > // accessor functions
    > > double getWidth() { return width; }
    > > double getHeight() { return height; }
    > > void setWidth(double w) { width = w; }
    > > void setHeight(double h) { height = h; }
    > > char *getName() { return name; }

    >
    > > // area() is now a pure virtual function
    > > virtual double area() = 0;

    >
    > > };

    >
    > > // Triangle is derived from TwoDShape.
    > > class Triangle : public TwoDShape {
    > > char style[20]; //now private
    > > public:

    >
    > > /* A default constructor. This automatically invokes
    > > the default constructor of TwoDShape. */
    > > Triangle() {
    > > strcpy(style, "unknown");
    > > }

    >
    > > // Constructor with three parameters.
    > > Triangle(char *str, double w, double h)
    > > : TwoDShape(w, h, "triangle") {
    > > strcpy(style, str);
    > > }

    >
    > > // Construct an isosceles triangle.
    > > Triangle(double x) : TwoDShape(x, x, "triangle") {
    > > strcpy(style, "isosceles");
    > > }

    >
    > > // This now overrides area() declared in TwoDShape.
    > > double area() {
    > > return getWidth() * getHeight() / 2;
    > > }

    >
    > > void showStyle() {
    > > cout << "Triangle is " << style << "\n";
    > > }
    > > };

    >
    > > int main() {
    > > // declare an array of pointers to TwoDShape objects.
    > > TwoDShape *shapes[4];

    >
    > > shapes[0] = &Triangle("right", 8.0, 12.0);
    > > shapes[1] = &Triangle(3.0);
    > > shapes[2] = &Triangle(4.0);
    > > shapes[3] = &Triangle(7.0);

    >
    > > for(int i=0; i < 2; i++) {
    > > cout << "object is " <<
    > > shapes->getName() << "\n";

    >
    > > cout << "Area is " <<
    > > shapes->area() << "\n";

    >
    > > cout << "\n";
    > > }

    >
    > > return 0;
    > > }

    >
    > > Hi, I'm a beginning programmer. Above is the code that is giving me
    > > the error. I have talked with a professor about this issue. The
    > > error happens on the lines beginning "shapes[0] = ... "

    >
    > > The professor says, because Triangle was created without a variable
    > > they are temporary objects. Which means they will be destroyed and
    > > the pointer becomes a dangling pointer.

    >
    > > I edited the code and just created the objects and gave them a
    > > variable to be stored in. i.e. "Triangle t1("right", 4, 5);" Then I
    > > just do "shapes[0] = &t1;" When I recompile, I get no warnings and it
    > > runs as expected.

    >
    > > My question: Is there a way so that the temporary objects are not
    > > destroyed? Seems like a waste of memory to create a variable outside
    > > of the array that will always be referenced through the array.

    >
    > The simplest (as in requires the least change in the code) way to do
    > this is to use new to allocate the Triangles on the heap (dynamic
    > memory). Objects created with new will continue to exist until they are
    > explicitly deleted (even if you no longer have a pointer or reference to
    > them!). This means that when you no longer need an object created with
    > new you must delete them or your program will use up all memory.
    >
    > To create a Triangle using new do this:
    >
    > shapes[0] = new Triangle("right", 8.0, 12.0);
    >
    > And when you are done with it you use delete to delete them:
    >
    > delete shapes[0];
    >
    > I guess that you have not discusses dynamic memory in class, beware that
    > there are some problems with it if you are not careful and it is
    > therefore generally a good idea not to use it, but sometimes you have to.
    >
    > --
    > Erik Wikström- Hide quoted text -
    >
    > - Show quoted text -


    Yes the suggestion of using the new keyword solves the issue. Thanks
    for the response.

    I am actually taking a refresher on C++ and dynamic memory has not
    been discussed yet. But I do recall the dangers of it. Again thanks
    for the help!
     
    , May 8, 2007
    #4
    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. Henning Hasemann
    Replies:
    17
    Views:
    1,174
    mangesh
    Jun 30, 2006
  2. Replies:
    0
    Views:
    1,132
  3. Replies:
    7
    Views:
    3,308
    James Kanze
    Feb 12, 2008
  4. Andy Gibbs
    Replies:
    5
    Views:
    4,108
    Andy Gibbs
    Nov 19, 2008
  5. V.Subramanian, India

    taking address of temporary object

    V.Subramanian, India, Feb 10, 2012, in forum: C++
    Replies:
    2
    Views:
    1,069
    Alf P. Steinbach
    Feb 10, 2012
Loading...

Share This Page