Re: Templates, Structs and Invalid Pointers - where did it go wrong
On Aug 28, 3:35 am, DaveJ <davej2...@gmail.com> wrote:
Recently I was working on a project where I came across an issue where
the program cored and reported "free(): invalid pointer".
I found a resolution for this, but don't fully understand why the
issue occurred in the first place.
The project uses a simple template class that acts as a buffer.
Initially it has a fixed length, but it's append methods will extend
the size of the buffer if necessary.
...
Anyway I've included a cut down and simplified version of the code
below. I found the resolution was to modify the struct so that it
takes a reference to the template class.
------ VarBuf Class <VarBuf.h> ------
#ifndef __TVARBUF_H__
#define __TVARBUF_H__
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
template<size_t N> class TVarBuf
{
public:
TVarBuf (const char *initStr);
~TVarBuf ();
private:
char m_Buf[N + 1];
char* m_Str;
size_t m_Capacity;
size_t m_Length;};
#endif
template<size_t N>
TVarBuf<N>::TVarBuf(const char *initStr) :
m_Str(NULL),
m_Capacity(N),
m_Length(0)
{
m_Str = m_Buf;
m_Str[0] = '\0';
.....
}
template<size_t N>
TVarBuf<N>::~TVarBuf()
{
if(m_Str != m_Buf)
{
free(m_Str);
}
}
Destructor frees invalid pointer eventually if object was created by
memmove, default-copy, or default-assignment. Evidently you already
noticed this.
---------------------------------
---- Main App <main.cpp> -----
1 #include "VarBuf.h"
2 #include "stdio.h"
3 #include "time.h"
4 typedef TVarBuf<6> ProfKey; // Create a typedef for our template
class
5 typedef struct
6 {
7 time_t m_CurrTime;
8 int m_Docs;
9 int m_OldDocs;
10 ProfKey m_OldestProfUrl; // this is the template class
11 } Prof;
This should be an aggregate non-POD-struct, so there is no reason to
try to be both C and C++. It would be typical style both to rewrite
as a non-typedef'd struct as mentioned in an earlier post, and use the
C++-specific standard headers.
You'll miss some archaic C++ compiler bugs by sacrificing aggregate
initialization and rewriting (modulo style guidelines) as
class Prof
{
public:
time_t m_CurrTime;
int m_Docs;
int m_OldDocs;
ProfKey m_OldestProfUrl; // this is the template class
Prof(time_t _m_CurrTime, int _m_Docs, int _m_OldDocs, const char*
InitStr)
: m_CurrTime(_m_CurrTime),
m_Docs(_m_Docs),
m_OldDocs(_m_OldDocs),
m_OldestProfUrl(InitStr) {};
};
Default assignment/copy-construction/destruction should work if your
template class' overrides of these work.
....
------------------------------------------
Compiling the above code with the following command
g++ -g -Wall -omain main.cpp
Exact version?
and running the main binary results in:
free(): invalid pointer 0xbfffd66c!
I modified the code slightly so that line 10 of main reads:
-----------------------------------------------
ProfKey& m_OldestProfUrl; //take a reference to ProfKey
-----------------------------------------------
and line 17 now reads
------------------------------------------------
ProfKey key(NULL);
Prof profile = {now, 0, 0, key}
------------------------------------------------
Any explanation of whats going on here would be good.
I'd try ruling out bugs (aggregate initializer or getting confused by
non-POD-struct) first, especially since your target RH versions are
archaic. Rewrite Prof as a proper class (and use constructor rather
than aggregate initialization) to bypass these.