Problems with a string stack library
hi, follow on post issue having last week.
first background, i'm writing application involves creating , sending sms messages, if signal strength weak send message, need store message in list until it's strong enough. if signal strength stays weak long need start deleting oldest messages message list whilst still adding new messages. once signal strength has been restored need send whole stack of messages starting recent.
to i've written library (ministack.h , ministack.cpp, attached) , test sketch demonstrate it.
ministack.h
ministack.cpp
the news works. bad news can't work reliably once include in project. example sketch i've attached seems work time, once embed in full application seems fail (i.e. hang) @ random intervals, far can tell hangs when gets strdup function in addnew(). know strdup calls malloc, , call 'free' release memory later, think may @ root of problem. i've tried re-write function using strcpy instead (which doesn't call malloc) can't work. i've tried produce example sketch fail , therefore illustrate problem haven't managed either.
what i'd is
a) some experienced eyes have @ code , 'sanity check' it. and, either
b) spot bug, or
c) suggest different approach solve problem.
failing that, know of library i've after? least favourite option, i'd prefer understand i've done wrong.
finaly, please speak in replies, i'm new this!
unfortunately can't include whole project here, relies on other libraries , custom built shields.
p.s. example sketch demo library included in next post.
thanks
mike
first background, i'm writing application involves creating , sending sms messages, if signal strength weak send message, need store message in list until it's strong enough. if signal strength stays weak long need start deleting oldest messages message list whilst still adding new messages. once signal strength has been restored need send whole stack of messages starting recent.
to i've written library (ministack.h , ministack.cpp, attached) , test sketch demonstrate it.
ministack.h
code: [select]
#ifndef ministack_h //these lines (together #endif @ end of file) prevent
#define ministack_h //any problems occuring if library should included twice.
extern "c" {
#include <string.h>
}
#include <stdlib.h> //needed 'free'
#include "wprogram.h" //needed 'serial'
// define limits of stack
#define max_chars 160
#define max_elements 12
class stack
{
public:
// constructor
stack(void);
// add new element (i.e. string) array
void addnew(char *new_element);
// remove rightmost (i.e. newest) element array
void removenew();
// rightmost (i.e. newest) element array
char* getnew();
// display full stack
void displayall();
// actual number of messages in stack
inline int getactsize(){return sms_list_size;}
private:
char sms_mess[max_chars+1]; //full sms message (header, timestamp, location fixes , checksum)
char *sms_list[max_elements]; //array of messages, yet un-transmitted
int sms_list_size; //actual size of sms_list. (number of populated elements)
// shift every element in array 1 place left whislt keeping overall array size same
// have effect of dropping left-most element (i.e. oldest item on stack) and
// freeing right element. should used when new element has added
// stack full
void leftshift();
// endless loop. around the fact can't find 'stop' function arduino.
// traps processing in endless loop gives me time examine screen output
// before gets scrolled off top.
void endlessloop();
};
#endifministack.cpp
code: [select]
//#include <ministack.h>
#include "ministack.h"
extern "c" {
#include <string.h>
}
#include <stdlib.h> //needed 'free'
#include "wprogram.h" //needed 'serial'
// constructor
stack::stack()
{
}
////destructor
//stack::~stack()
//{
// end();
//}
void stack::addnew(char *new_element)
{
//add new message array. records added arrive left right.
//therefore rightmost fix should allways recent
if (sms_list_size == max_elements)
{
//the array of messsages @ maximum, therefore discard oldest fix
//to make room newest.
leftshift();
}
//add fix array. before attempting it, check string isn't big
if ( strlen(new_element) > max_chars )
{
serial.print("error, strdup. source length=<"); serial.print(strlen(new_element));serial.print(">. destination size=<");serial.print(max_chars);serial.println(">");
serial.print("existing element=<");serial.print(sms_list[sms_list_size]);serial.println(">");
endlessloop();
}
sms_list[sms_list_size]=strdup(new_element); //copy current message array of messages. note uses malloc, , therefore
//increase amount of memory being used.
//strcpy(sms_list[sms_list_size],new_element);
sms_list_size++; //increment counter records number of smss waiting transmitted.
//curr_sms[0]=0; //clear / reset current sms message
}
void stack::leftshift()
{
//shift entire contents of sms array left 1 element. leftmost element lost and
//a space freed on righthand side
free(sms_list[0]); //frees memory 1st (i.e. leftmost element in array). note - this
//should free same amount of memory taken strdup command earlier.
//so there should no net increase in memory usage.
sms_list[0]=0;
for (int n=0; n<sms_list_size; n++)
{
sms_list[n]=sms_list[n+1];
}
sms_list[sms_list_size-1]=0; //frees pointer 'newest' element in memory
sms_list_size--; //decrement counter records number of fixes waiting transmitted.
}
void stack::displayall()
{
//display whole list
serial.println("whole stack follows.....");
for (int n=0; n<=max_elements-1; n++)
{
serial.print(n); serial.print(" ");
serial.println(sms_list[n]);
}
}
char* stack::getnew()
{
//display rightmost message in arry (i.e. added)
return sms_list[sms_list_size-1];
}
void stack::removenew()
{
//set rightmost element of message array null.
if (sms_list_size >= 1) //check index within bounds
{
free(sms_list[sms_list_size-1]); //free memory
sms_list[sms_list_size-1]=0; //delete/reset pointer memory
sms_list_size--; //decrement size counter
}
}
void stack::endlessloop()
{
// endless loop 'stop' processing. allows errors trapped , examined on screen
// before scroll off top of screen!
while ( 1==1 )
{
serial.print(".");
//pause 5 seconds
delay(5000);
}
}the news works. bad news can't work reliably once include in project. example sketch i've attached seems work time, once embed in full application seems fail (i.e. hang) @ random intervals, far can tell hangs when gets strdup function in addnew(). know strdup calls malloc, , call 'free' release memory later, think may @ root of problem. i've tried re-write function using strcpy instead (which doesn't call malloc) can't work. i've tried produce example sketch fail , therefore illustrate problem haven't managed either.
what i'd is
a) some experienced eyes have @ code , 'sanity check' it. and, either
b) spot bug, or
c) suggest different approach solve problem.
failing that, know of library i've after? least favourite option, i'd prefer understand i've done wrong.
finaly, please speak in replies, i'm new this!
unfortunately can't include whole project here, relies on other libraries , custom built shields.
p.s. example sketch demo library included in next post.
thanks
mike
example sketch promised....
code: [select]
#include <memoryfree.h>
#include <ministack.h>
// note - these 2 variables need set same values 'max_chars' , 'max_elements'
// in ministack.h
const int sms_len = 160; //maximum allowable sms length
const int max_sms_list_size = 12; //number of unsent smss can stored
char curr_sms[sms_len+1]; //current sms.
int mess_seq_num=0; //message sequence number
const int max_mess_seq_num=9999; //maximum message sequence number (before reseting 0)
char mess_text[]="mymessage-";
stack mystack;
int sms_list_size=0; //actual size of sms_list. (number of populated elements)
long sms_lost=0; //counts number of messages lost because buffer full.
// random number
long randnumber=0;
void setup()
{
serial.begin(115200); //communication speed display
serial.println("starting.........");
randomseed(analogread(0));
}
void loop()
{
serial.println();serial.print("freememory reports <");serial.print( freememory() );serial.println("> (bytes) free");
//create random message
createmess();
//add message stack
mystack.addnew(curr_sms);
//display current message
serial.print("current message <");serial.print(curr_sms);serial.println(">");
//display stack
mystack.displayall();
serial.println("current message is.....");
serial.print(" <");serial.print(mystack.getnew());serial.println(">");
//when signal strength enough, recent message should sent , removed the
//array. simulate 1 in 4 chance of success.....
int randnumber = random(4);
if (randnumber == 1)
{
//remove random number (between 0 , all) of messages stack
int n=random(mystack.getactsize());
serial.print("removing recent <");serial.print(n);serial.println("> messages");
for (int i=0 ;i<n; i++)
{
serial.println("about remove following message stack.");
serial.print(" <");serial.print(mystack.getnew());serial.println(">");
//remove rightmost (i.e. recent) message array.
mystack.removenew();
}
}
//slow things down bit...
delay(1000);
}
void createmess()
{
// creates simple, variable length text string example only
int message_size;
char mess_seq_str[4+1]; //message sequence number expressed string
message_size=random(1,8);
sprintf(mess_seq_str,"%.4d",mess_seq_num); //format sequence number 4 digit string leading zeros
curr_sms[0]=0; //reset/clear current message
//create message
for (int i=0; i<message_size ;i++)
{
strcat(curr_sms,mess_text);
strcat(curr_sms,mess_seq_str);
}
//increment or reset counter
if (mess_seq_num < max_mess_seq_num)
{
mess_seq_num++;
}
else
{
mess_seq_num=0;
}
}
Arduino Forum > Forum 2005-2010 (read only) > Software > Syntax & Programs > Problems with a string stack library
arduino
Comments
Post a Comment