Advertisement

Overloading << for a memory manager

Started by August 23, 2000 08:10 AM
1 comment, last by gimp 24 years, 4 months ago
I''m wrinting a memory manager that''ll allow me to do things that I can do with the old trusty vector, like memcpy''ing in globs of ram over the top of it(copying in structs(.. to be done later, not below)). I seem to have hit a snag on the << operator however. #include "malloc.h" #include "memory.h" #include "string.h" #include "assert.h" class ByteArray { public: void operator<<(const char *p) { unsigned long newsize = _Size + strlen(p) +1; if (_Array) { _Array = (unsigned char*)malloc(newsize); assert(_Array); } else { _Array = (unsigned char*)realloc(_Array,_Size); assert(_Array); } memcpy(_Array + _Size,p,newsize); _Size=newsize; _Array[_Size] = NULL; } unsigned char operator[](unsigned long index) {return _Array[index];} unsigned long size() { return _Size; } ~ByteArray() { free(_Array); } private: unsigned char *_Array; unsigned long _Size; }; void main(void) { ByteArray *Data = new ByteArray; Data << "hello"; } I''m getting error when I try to use the << operator. Would someone be kind enough to tell me what I''m doing wrong here? Also if anyone would like to offer advise on the best way of making << generic across diferent data types I''m interested. I was thinking about making it unsigned char an making the user cast. Is there a better way that''ll allow a user to send in a pointer to a custom struct and have it still work? Thanks again... gimp
Chris Brodie
You have two problems:
1. You miss a constructor that sets _Array and _Size to NULL (well, I guess you just forgot to paste it)
2. You are doing memory allocation the wrong way around.
    if (_Array) // meaning: if (_Array != NULL){   _Array = (unsigned char*)malloc(newsize); // malloc? wouldn''t it better be realloc?   assert(_Array);} else { // if (_Array == NULL)   _Array = (unsigned char*)realloc(_Array,_Size); // here is the place for malloc   assert(_Array);}[/source]About the generic operator:[source]template <class T> ByteArray & operator (const T & data){   WriteData(&data, sizeof data);   return *this;}    


Ah, yes, and your operator should return *this, not void. That might cause the problem too. This template code might perhaps not work with all compilers.
Advertisement
opperators are syntactic sugar, and can get confusing. Your fisrt problem is you are calling << on a ByteArray * not a ByteArray. The next one is that << generally does not imply append, but rather "send to" (or even shift). += is the normal way to do this.

      class ByteArray {  ...  void Append(const string &s) {//    realloc and so forth  }};inlineByteArray & operator +=(ByteArray &a,const string &s) {  a.Append(s);  return a;}/*  This nest one  can be confusing, but it lets you say   data += "Hello"; rather than *data += "Hello";*/inlineByteArray & operator +=(ByteArray *a,const string &s) {  if(a==0) throw bad_arg("+= given null ByteArray");  a->Append(s);  return *a;}    


you may want to replace the throw with a call to a function that throws the exception, as it tends to expand quite a bit inline, and is not in the normal flow of execution. Or just assert()

It would be interesting to profile your new class against vector. I would suggest at least allocating 2K more than you need or keep a running average of the typical sise of appends and allocating at least twice that ammount.

Also note that under windows realloc() is not guaranteed to return the same pointer you passed it (it can move the block). you may want to look up _expand(). Also realloc() acts just like malloc if you pass it a NULL pointer, so your if is redundant (unless you use _expand())

This topic is closed to new replies.

Advertisement