3

So, I'm kind of a beginner at C++ ... I thought I had a firm grasp of dynamic memory allocation but I guess I don't. I've searched the net for numerous solutions but I still cannot fix my problem. I keep getting error 0xC00000FD:Stack overflow when I run debug. I'm pretty sure the problem has to do with the way I'm allocating memory in the default constructors but maybe it's something else. I guess I need some deeper insight. Any help or hint in determining the problem would be greatly appreciated.

It's a simple program to calculate area and perimeter of a rectangle from user input.

This is the header file:

#pragma once
class my_Rectangle
{
private:
    float m_area;
    float m_perimeter;
    float m_length;
    float m_width;
    void update_rec();
    my_Rectangle*tempSTORE;
public:
    float calc_area(float length,float width);
    float calc_perim(float length,float width);
    void change_RECTsize(float length,float width,my_Rectangle tempSTORE);


    my_Rectangle(); //constructor
    my_Rectangle(float length,float width);
    ~my_Rectangle(); //destructor
};

This is the class member definitons file:

#include "StdAfx.h"
#include "my_Rectangle.h"
#include <iostream>

//using namespace std;

//This function calculates the area
float my_Rectangle::calc_area(float length,float width)
{
    float area = width * length;

    std::cout<<"\nThe area of the rectangle is: "<<area<<" square metres."<<std::endl;  // ::scope operater
    return area;
}

//This function calculates the perimeter
float my_Rectangle::calc_perim(float length,float width)
{
float perimeter=(2*length)+(2*width);

std::cout<<"\nThe perimeter of the rectangle is "<<perimeter<<" metres."<<std::endl;
return perimeter;
}
//this function changes the size of the rectangle
void my_Rectangle::change_RECTsize(float length,float width,my_Rectangle tempSTORE)
{
    tempSTORE.m_length=length;
    tempSTORE.m_width=width;
    my_Rectangle::calc_area(length,width);
    my_Rectangle::calc_perim(length,width);
}



my_Rectangle::my_Rectangle() //default constructor
{
    tempSTORE=new my_Rectangle;

    tempSTORE->m_length=0.00;
    tempSTORE->m_width=0.00;
    tempSTORE->m_area=0.00;
    tempSTORE->m_perimeter=0.00;

}
my_Rectangle::my_Rectangle(float length,float width) //initialized constructor
{
    tempSTORE=new my_Rectangle;

    tempSTORE->m_length=length;
    tempSTORE->m_width=width;
    calc_area(length,width);
    calc_perim(length,width);
}


my_Rectangle::~my_Rectangle() //destructor
{
     delete tempSTORE;
std::cout<<"\nThe memory has been freed!!"<<std::endl; 

And this is the client file:

#include "stdafx.h"
#include "my_Rectangle.h"
#include <iostream>
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    float xlength,xwidth;

    cout<<"Welcome to the rectangle Area Calculator!"<<endl;
    cout<<"Please enter the length and width of your rectangle:"<<endl;
    cout<<"Length: "; cin>>xlength;
    cout<<"Width: "; cin>>xwidth;


    cout<<"Rectangle Information:"<<endl;
    cout<<"Length: "<<xlength<<"m\tWidth: "<<xwidth<<" m"<<endl;
    my_Rectangle userRECT(xlength,xwidth);

    reTRY:
    int user_choice;
    cout<<"More options:"<<endl;
    cout<<"1. Change rectangle size"<<endl;
    cout<<"2. Exit"<<endl;
    cout<<"Enter a number: ";
    cin>>user_choice;
    switch (user_choice)
    {
    case 1:
        cout<<"Please enter the new length and width of rectangle:"<<endl;
        cout<<"Length: "; cin>>xlength;
        cout<<"Width: "; cin>>xwidth;
        cout<<"\nRectangle Information:"<<endl;
        cout<<"Length: "<<xlength<<"m\tWidth: "<<xwidth<<" m"<<endl;
        userRECT.change_RECTsize(xlength,xwidth,userRECT);
        break; 
    case 2:
        exit(1);
        break; 
    default: cout<<"\nThat is not a valid option. Please try again!" ;
     goto reTRY;
     break; 
    }


     cin.get();cin.get();
    return 0;
}
10
  • 3
    By the way--never use goto in C++. Ever. Whoever (told you / showed you / implied to you / telepathically communicated to you) that goto was a good or useful idea in C++ was wrong. Never use it. Ever. Commented Nov 27, 2013 at 16:43
  • Unrelated to your question, but change_RECTsize takes a my_rectangle by value. The modifications performed will only affect the copy which is probably not what you intended. Consider passing it by reference instead. Commented Nov 27, 2013 at 16:43
  • Remove tempSTORE from Rectangle. If you want a temporary variable for some calculation then declare it when you need it, don't put it in your class. Commented Nov 27, 2013 at 16:46
  • François Moisan ,I saw that too but I wasn't sure if I could pass a class by reference or by pointer. Is it possible? Commented Nov 27, 2013 at 16:49
  • 2
    Use a loop instead of the goto. Commented Nov 27, 2013 at 17:07

2 Answers 2

9

Stack overflows have little to do with dynamic allocation - the stack is for function calls and local variables (static & automatic allocation). But you do have infinite recursion in your default constructor:

my_Rectangle::my_Rectangle() //default constructor
{
    tempSTORE=new my_Rectangle;

This will allocate tempSTORE and call the default constructor on it, which will allocate a tempSTORE, which ...


You seem to be confused about the order of memory and construction operations. Constructors and destructors run on memory already allocated by someone else. The sequence is as follows:

  1. Memory is allocated in some way (on the stack for a local variable, on the heap via new)
  2. A constructor is automatically executed in the memory
  3. Object lives
  4. Object death is initiated (local variable goes out of scope, somebody calls delete)
  5. Destructor is automatically executed in the memory
  6. The memory is freed

This means your constructor should not be concerned about obtaining memory for the object it's constructing, it's been already provided by someone. Neither should the destructor care about releasing memory occupied by the object itself, that will be done by someone else once the destructor ends.

To learn more about this, I suggest you follow a good book.

Sign up to request clarification or add additional context in comments.

6 Comments

So, how best should I approach this issue of allocating memory dynamically to a newly created class object? Originally, I hadn't defined tempSTORE in the class declaration, but without it,the destructor doesn't recognize the newly created pointer to allocated memory of my_Rectangle class .. i.e in the constructor: my_Rectangle *tempSTORE =new my_Rectangle //memory allocation for new class object .... in the destructor: delete tempSTORE; //tempSTORE is not recognized (undefined)
@nilerafter24 Why does tempSTORE exist? I do not see the point what you are trying to do with that.
@nilerafter24 I've expanded the answer.
Okay, I'm going to dump tempSTORE from my code and try what you say. Thanks for all the help! I'll do some more in depth reading on memory allocation. I'm using C++ Primer Plus by Stephen Prata which some friends recommended to me. It's easy to use at first but these later chapters are a bit daunting. I'll try to take a look at the other books. The transition from C to C++ is not as easy as I thought it would be.
@nilerafter24 Note that the book list I linked does not exactly recommend C++ Primer Plus...
|
3
my_Rectangle::my_Rectangle() //default constructor
{
    tempSTORE=new my_Rectangle;

There's the problem - new my_Rectangle calls this constructor, falling into a recursive death spiral as it tries to create an infinite chain of rectangles.

I've no idea how to fix it, since I've no idea what tempSTORE is supposed to be. You seem to be writing random values into it, and never reading them back - it doesn't look like it should exist at all. In any case, you certainly can't create it in this manner in this place.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.