This is wrong on a number of levels. First in the class declaration:
char content[];
That gives you a pointer to an array of zero length.
This gives you an array of char, of zero length. This is not useful.
char* content = new char[_len];
content = _chars;
That does a new
into a new variable content
- not the class variable. Then you assign (overwrite) the passed pointer into content
(discarding the memory you just allocated). That pointer is then discarded when the constructor ends. Perhaps using strcpy
would be better.
I made up a small example based on your code which prints the correct result:
class bufr
{
public:
//constructor and deconstructor
bufr(char* chars, uint8_t len);
~bufr();
//variables
uint8_t len_;
char * content_;
}; // end of class bufr
bufr::bufr(char* chars, uint8_t len)
{
content_ = new char[len];
memcpy (content_, chars, len); // copy into allocated memory
len_ = len; // remember length
} // end of constructor
bufr::~bufr()
{
delete [] content_;
} // end of destructor
void setup()
{
Serial.begin (115200);
char chars[] = "1234 ";
bufr buf(chars, sizeof chars);
Serial.println (buf.content_);
} // end of setup
void loop()
{
} // end of loop
Can you explain to me why it was making a new variable content and not using the class variable?
Small example:
char * content;
void loop ()
{
char * content = "foo"; // makes a NEW variable
}
In this example there are two variables named content
. The one in the function "shadows" the global one. However the code below only has one variable:
char * content;
void loop ()
{
content = "foo"; // uses existing variable
}
In the destructor, when you delete the pointer to the array, does this free up the memory allocated to the array? It's now free to be assigned again by something else? Or does it sit there still initialized as that array, not being able to be used again?
You aren't deleting the pointer. You are deleting the memory it points to. The pointer is now pointing to freed memory, so using it as a pointer at this stage would be wrong. You can do another new
to make it point to something else.
they delete pointer and then delete[] pointer.
You misinterpreted that. You either delete pointer
or delete [] pointer
depending on whether pointer
is an array or not. I reworked content
to not be an array, thus deleting it without the brackets is correct however as it is allocated using new []
it must be deleted with delete []
.
on the link posted above they say to use delete this way: delete pointer if it was a single element allocated with new or delete [] pointer to release memory allocation for arrays of elements allocated with new and a size in []'s. So in my case I want to use delete [] content_?
No, you don't want to be setting up an array in the first place. Take a look at this small example:
struct {
char bar [];
} foo;
void setup()
{
Serial.begin (115200);
Serial.println ("Starting");
Serial.println (sizeof (foo));
Serial.println (sizeof (foo.bar));
}
void loop()
{
}
That prints:
Starting
0
0
The variable bar
is a zero-length array. Thus the entire struct foo
is also zero length. It isn't even a pointer (that would be two bytes on this platform).
It is wrong to use an array of char like that, when you want to dynamically allocate memory. Look at this:
char foo [4];
That allocates 4 bytes of memory for foo
. You can't later on make it longer by doing a new
.
What you want is:
char * foo;
Now you have allocated a pointer and can do a new
, like this:
foo = new char [10]; // allocate 10 bytes
And then delete it:
delete [] foo;
You use the brackets on the delete, as you used them with the new
.
If you allocated one char you wouldn't use brackets. eg.
char * foo;
foo = new char; // allocate a pointer to one byte
...
delete foo;