Hi
I wanted to use a little cpp source code in an arduino sketch, but it used the stack library from STL, so i decided to make my own just like it. Following the libraries tutorial on the arduino website i put together this:
Stack.h:
#ifndef STACK_H
#define STACK_H
template <class T>
class Stack {
public:
//Constructor
Stack ();
//Destructor
~Stack ();
//Add an item to the stack
void push (T item);
//See the top item of the stack
T top ();
//Remove the top item of the stack
void pop ();
//Check if the stack is empty
bool empty();
private:
struct element
{
T value;
element *next;
};
struct main
{
int elements;
element *top;
};
main * _main;
element * _new, * _old;
void deleteStack (element * el, int i);
};
#endif // STACK_H
But it didnt exactly work! i think that it is because of the template thing but i dont know. The arduino IDE said this:
stack.cpp.o: In function `__static_initialization_and_destruction_0':
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:5: undefined reference to `Stack<int>::Stack()'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:5: undefined reference to `Stack<int>::~Stack()'
stack.cpp.o: In function `setup':
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:9: undefined reference to `Stack<int>::push(int)'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:10: undefined reference to `Stack<int>::top()'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:11: undefined reference to `Stack<int>::pop()'
C:\Users\Moni\AppData\Local\Temp\build4110618608836428356.tmp/stack.cpp:12: undefined reference to `Stack<int>::empty()'
Please help me! I really want to make this work !! Thanks in advanced
Seems to be a linker problem. The IDE did not find the Stack.cpp object code. In my own project I usually create a "utility" folder which contains my additional code. The utility folder seems to be analysed by the Arduino IDE. Indeed to me it is still an open question which are the search pathes of the Arduino IDE.
#include <Stack.h>
Stack <int> st;
void setup ()
{
st.push(5);
int a = st.top();
st.pop();
bool b = st.empty();
}
void loop ()
{
}
All the files are in their proper places and are properly named. I also took a look at Templates, C++ FAQ and tried a few things but they didn`t work. Any more ideas?
If you take the .h file from your original post, and add the function implementations that you have in the cpp file to make each function inline, you're almost there. e.g.
template <class T>
class Stack {
public:
//Constructor
Stack ()
{
_main = new main;
_main.elements = 0;
}
Now, replace all of the periods with ->, because the data members you're addressing are pointers
Now, it will compile and link. If you have problems, try creating a new sketch and pasting the following, which is the new header file as described above, plus your test code from your most recent post and the new and delete implementations, all in one file.
void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }
template <class T>
class Stack {
public:
//Constructor
Stack ()
{
_main = new main;
_main->elements = 0;
}
//Destructor
~Stack ()
{
deleteStack ( _main->top, _main->elements-1 );
delete _main;
}
//Add an item to the stack
void push (T item)
{
_new = new element;
_new->value = item;
_new->next = _main->top;
_main->top = _new;
}
//See the top item of the stack
T top ()
{
return _main->top->value;
}
//Remove the top item of the stack
void pop ()
{
_old =_main->top;
_main->top = _main->top->next;
delete _old;
}
//Check if the stack is empty
bool empty()
{
if(!_main->elements)return false;
else return true;
}
private:
struct element
{
T value;
element *next;
};
struct main
{
int elements;
element *top;
};
main * _main;
element * _new, * _old;
void deleteStack (element * el, int i)
{
if(i) deleteStack ( el->next , i-1 );
delete el;
}
};
Stack <int> st;
void setup ()
{
st.push(5);
int a = st.top();
st.pop();
bool b = st.empty();
}
void loop ()
{
}
Hi, kerthyn,
Thanks for the help! I did as told me but it still doesn`t work this the header file, i think i got everything right.
#ifndef STACK_H
#define STACK_H
void * operator new( size_t size ) { return malloc( size ); }
void operator delete( void * ptr ) { if ( ptr ) free( ptr ); }
template <class T>
class Stack {
public:
//Constructor
Stack ()
{
_main = new main;
_main->elements = 0;
}
//Destructor
~Stack ()
{
deleteStack ( _main->top, _main->elements-1 );
delete _main;
}
//Add an item to the stack
void push (T item)
{
_new = new element;
_new->value = item;
_new->next = _main->top;
_main->top = _new;
}
//See the top item of the stack
T top ()
{
return _main->top->value;
}
//Remove the top item of the stack
void pop ()
{
_old =_main->top;
_main->top = _main->top->next;
delete _old;
}
//Check if the stack is empty
bool empty()
{
if(!_main->elements)return false;
else return true;
}
private:
struct element
{
T value;
element *next;
};
struct main
{
int elements;
element *top;
};
main * _main;
element * _new, * _old;
void deleteStack (element * el, int i)
{
if(i) deleteStack ( el.next , i-1 );
delete el;
}
};
#endif // STACK_H
And these are the cimpiller errors:
In file included from stack.cpp:1:
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:4: error: declaration of 'operator new' as non-function
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:4: error: 'size_t' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h: In function 'void operator delete(void*)':
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:5: error: 'free' was not declared in this scope
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h: In member function 'void Stack<T>::deleteStack(Stack<T>::element*, int) [with T = int]':
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:22: instantiated from 'Stack<T>::~Stack() [with T = int]'
stack.cpp:5: instantiated from here
C:\Program Files (x86)\Arduino\libraries\Stack/Stack.h:75: error: request for member 'next' in 'el', which is of non-class type 'Stack<int>::element*'
There's no need for a stack.cpp; everything you need is in stack.h. Just delete stack.cpp from your sketch folder (keep a copy somewhere.) If you include stack.h in your main sketch file (or in whatever file needs stack<>), all should be well, except...
The new and delete functions should be defined only once (i.e. the implementation should only appear in one place.) You can put these in a separate file in your sketch folder (and the IDE will append that file to your sketch file before compilation,) or you can simply add them somewhere in your main sketch. You shouldn't need to declare these functions in your .h file, so remove those lines:
When i put new and delete in the sketch it compiles, but not when they are in a file. BTW should i put anything else in that file or leave it just as it is? :
The iterations towards fixing this are unlikely to be of interest to others; check you private messages. When it's all working you can post the solution, which might be useful to others.
/*
Stack - library supporting the stack container.
Written by Simeon Dorelov
Date: 9 August 2011
*/
#ifndef STACK_H
#define STACK_H
#include <CppSupport.h>
template <class T>
class Stack {
public:
//Constructor
Stack ()
{
_main = new main;
_main->elements = 0;
}
//Destructor
~Stack ()
{
deleteStack ( _main->top, _main->elements-1 );
delete _main;
}
//Add an item to the stack
void push (T item)
{
_new = new element;
_new->value = item;
_new->next = _main->top;
_main->top = _new;
_main->elements++;
}
//See the top item of the stack
T top ()
{
return _main->top->value;
}
//Remove the top item of the stack
void pop ()
{
_old =_main->top;
_main->top = _main->top->next;
delete _old;
_main->elements--;
}
//Check if the stack is empty
bool empty()
{
if(!_main->elements)return true;
else return false;
}
//Check the number of elements in the stack
int size ()
{
return _main->elements;
}
private:
struct element
{
T value;
element *next;
};
struct main
{
int elements;
element *top;
};
main * _main;
element * _new, * _old;
void deleteStack (element * el, int i)
{
if(i) deleteStack ( el->next , i-1 );
delete el;
}
};
#endif // STACK_H