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;
}
Emmanuel N K
  • 8,710
  • 1
  • 31
  • 37
  • 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. – riwalk Nov 27 '13 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. – François Moisan Nov 27 '13 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. – john Nov 27 '13 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? – Emmanuel N K Nov 27 '13 at 16:49
  • @nilerafter24 Both of these are possible. – john Nov 27 '13 at 16:52
  • @John, I wanted to create a memory in the heap to store the class object that gets created in the client file. Does this mean that I should allocate memory dynamically outside of the class member definitions(in the client file)? – Emmanuel N K Nov 27 '13 at 16:52
  • @Stargazer712, what can I use instead of goto? I want the program to do a re-try of the user prompt if the user enters something wrong – Emmanuel N K Nov 27 '13 at 16:54
  • @nilerafter24 I'm not sure what you are trying to do. It certainly doesn't feel right to have a temp object inside your class. – john Nov 27 '13 at 16:55
  • 2
    Use a loop instead of the goto. – drescherjm Nov 27 '13 at 17:07
  • @nilerafter24, use a loop. Either a `while` loop or a `do ... while` loop will work nicely. Never use `goto`. Ever. – riwalk Nov 27 '13 at 18:01

2 Answers2

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.

Community
  • 1
  • 1
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • 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) – Emmanuel N K Nov 27 '13 at 17:05
  • @nilerafter24 Why does tempSTORE exist? I do not see the point what you are trying to do with that. – drescherjm Nov 27 '13 at 17:10
  • @nilerafter24 I've expanded the answer. – Angew is no longer proud of SO Nov 27 '13 at 17:11
  • 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. – Emmanuel N K Nov 27 '13 at 17:29
  • @nilerafter24 Note that the book list I linked does not exactly recommend C++ Primer Plus... – Angew is no longer proud of SO Nov 27 '13 at 17:46
  • I finally understood it thanks to you guys. I now understand why the recursion was occurring when I allocated memory to tempSTORE (I have no idea what I was trying to accomplish by making it a class member. Probably tired). My code is working perfect now. – Emmanuel N K Nov 28 '13 at 02:15
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.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644