0
votes

I have written some class that moves heap allocated stuff to stack (hopefully :) ). This calss is singleton because only this class should be responsible for holding and managing part of stack. My question is: Is my code correct? Code is correct in the sense of programming (no compile errors, no memory errors and leaks (checked by valgrind)). But does the code really moves heap to stack? Here's the code:

stack.hpp:

class CStack{
public:
  void* getAlloc(long);
  static CStack* Instance();

private:
  static bool _data[5*sizeof(double)];
  static CStack* m_pInstance;

  CStack(){};
  CStack(const CStack&);
  CStack& operator=(const CStack&);
};

stack.cpp:

#include <iostream>
#include "stack.hpp"

CStack* CStack::m_pInstance = 0;

bool CStack::_data[ 5*sizeof(double) ] = { 1 };

CStack* CStack::Instance(){
  if (!m_pInstance)
    m_pInstance = new CStack;
  return m_pInstance;
}

void* CStack::getAlloc(long size){
  std::cout << "  CStack::getAlloc, " << _data << std::endl;
  _pos+=size;
  return &_data[0];
}

store.hpp

class CStore{
public:
  CStore();
  double* myAddr();
  void toStack();
  void out();
  ~CStore();
private:
  double *_data;
  bool _stack;
};

store.cpp:

#include <iostream>
#include <cstring>
#include "store.hpp"
#include "stack.hpp"

CStore::CStore(){
  _data = new double[4];
  _data[0] = 0.1;
  _data[1] = 1.1;
  _data[2] = 2.1;
  _data[3] = 3.1;
  _stack = 0;
}

double* CStore::myAddr(){ return _data; }

void CStore::toStack(){
  double *tmp;

  tmp = (double*)CStack::Instance() -> getAlloc(4*sizeof(double));

  memcpy(tmp, _data, 4*sizeof(double));
  delete [] _data;
  _data = tmp;
  _stack = 1;
}

CStore::~CStore(){
  if (!_stack)
    delete [] _data;
}

void CStore::out(){
  std::cout << _data[0] << " " << _data[1] << " " << _data[2] << " " << _data[3] << std::endl;
}

main.cpp:

#include <iostream>

#include "stack.hpp"
#include "store.hpp"

using namespace std;

int main(){
  CStack::Instance();
  CStore a;
  double stack;

  cout << &stack << endl;
  cout << "Adresa a " << a.myAddr() << endl;
  a.out();

  a.toStack();
  cout << "Adresa a " << a.myAddr() << endl;
  a.out();

  return 0;
}
1
Because internally you are using m_pInstance on the heap then surely the other parts are also allocated on the heap?Jim Jeffries
CStack* CStack::Instance(){ if (!m_pInstance) m_pInstance = new CStack; return m_pInstance;} implies that your object lives on the heap (see the non-placement new?).dmckee --- ex-moderator kitten
>> But does the code really moves heap to stack? It moves stuff to a collection called stack, but the collection itself is on the heap so no.Steve Wellens
I was afraid of it, because written addresses was far from address of var stack. I hope I could solve it by declare CStack::_data static, I was wrong. Is there any possibility to have singleton class that manages program stack?TauWich
How well do you understand the distinction between heap and stack? Are you aware that stack is a scarce resources in some systems and that using too much can get you into trouble? Do you know if your platform is one of those? How much memory do you intended to manage this way? And above all, why do you want to do this---we can't give good advice unless we know the reasoning behind this desire.dmckee --- ex-moderator kitten

1 Answers

0
votes

No it's utter nonsense.

First of all this code doesn't even use the stack (as long as we are speaking of the execution stack), and you clearly misunderstood the Singleton desing pattern.

You use Singleton, when you only need a single instance in your program, but you want to grant access to all functions to that single instance. Its like a global variable, but you can restrict the access.

Second, if you need to use casting in C++ like:

tmp = (double*)CStack::Instance() -> getAlloc(4*sizeof(double));

You've clearly gone wrong. Don't use void* in C++ for now. You can use it later, when you've gotten better, not for now.

The main question WHY do you wan't to move variables to the stack? if you simply want to allocate dynamicly, why still limiting it to the scope, use smart pointers, like std::auto_ptr.

if you want to create a stack, and use that to store your doubles you can write:

#include <vector>

int foo()
{
  std::vector<double> stack;

  // push values on the stack
  stack.push_back(1.1);
  stack.push_back(1.2);
  stack.push_back(1.3);

  // remove values from the stack
  stack.pop_back();
  stack.pop_back();
  stack.pop_back();
}