netgen/libsrc/general/table.cpp
Monty Montgomery ae87c7005c Two nullptr deref fixes in table
Don't delete memory that wasn't allocated.

Similarly, we can't deref the first element of an array that was never
allocated.
2022-05-15 01:16:58 -04:00

257 lines
5.2 KiB
C++

/**************************************************************************/
/* File: table.cpp */
/* Author: Joachim Schoeberl */
/* Date: 01. Jun. 95 */
/**************************************************************************/
/*
Abstract data type TABLE
*/
#include <mystdlib.h>
#include <myadt.hpp>
namespace netgen
{
//using namespace netgen;
BASE_TABLE :: BASE_TABLE (int size)
: data(size)
{
for (int i = 0; i < size; i++)
{
data[i].maxsize = 0;
data[i].size = 0;
data[i].col = NULL;
}
oneblock = NULL;
}
BASE_TABLE :: BASE_TABLE (const NgFlatArray<int> & entrysizes, int elemsize)
: data(entrysizes.Size())
{
size_t cnt = 0;
size_t n = entrysizes.Size();
for (size_t i = 0; i < n; i++)
cnt += entrysizes[i];
oneblock = new char[elemsize * cnt];
// mem_total_alloc_table += elemsize * cnt;
cnt = 0;
for (size_t i = 0; i < n; i++)
{
data[i].maxsize = entrysizes[i];
data[i].size = 0;
data[i].col = &oneblock[elemsize * cnt];
cnt += entrysizes[i];
}
}
BASE_TABLE :: ~BASE_TABLE ()
{
if (oneblock)
delete [] oneblock;
else
{
for (int i = 0; i < data.Size(); i++)
delete [] (char*)data[i].col;
}
}
void BASE_TABLE :: SetSize (int size)
{
for (int i = 0; i < data.Size(); i++)
delete [] (char*)data[i].col;
data.SetSize(size);
for (int i = 0; i < size; i++)
{
data[i].maxsize = 0;
data[i].size = 0;
data[i].col = NULL;
}
}
void BASE_TABLE :: ChangeSize (int size)
{
int oldsize = data.Size();
if (size == oldsize)
return;
if (size < oldsize)
for (int i = size; i < oldsize; i++)
delete [] (char*)data[i].col;
data.SetSize(size);
for (int i = oldsize; i < size; i++)
{
data[i].maxsize = 0;
data[i].size = 0;
data[i].col = NULL;
}
}
void BASE_TABLE :: IncSize2 (int i, int elsize)
{
#ifdef DEBUG
if (i < 0 || i >= data.Size())
{
MyError ("BASE_TABLE::Inc: Out of range");
return;
}
#endif
linestruct & line = data[i];
if (line.size == line.maxsize)
{
void * p = new char [(line.maxsize+5) * elsize];
if (line.size > 0 && line.col != NULL) {
memcpy (p, line.col, line.maxsize * elsize);
delete [] (char*)line.col;
}
line.col = p;
line.maxsize += 5;
}
line.size++;
}
void BASE_TABLE :: SetEntrySize2 (int i, int newsize, int elsize)
{
linestruct & line = data[i];
if (newsize > line.maxsize)
{
void * p = new char [newsize * elsize];
memcpy (p, line.col, min2 (newsize, line.size) * elsize);
delete [] (char*)line.col;
line.col = p;
}
line.size = newsize;
}
/*
void BASE_TABLE :: DecSize (int i)
{
#ifdef DEBUG
if (i < 0 || i >= data.Size())
{
MyError ("BASE_TABLE::Dec: Out of range");
return;
}
#endif
linestruct & line = data[i];
#ifdef DEBUG
if (line.size == 0)
{
MyError ("BASE_TABLE::Dec: EntrySize < 0");
return;
}
#endif
line.size--;
}
*/
void BASE_TABLE :: AllocateElementsOneBlock (int elemsize)
{
size_t cnt = 0;
size_t n = data.Size();
for (size_t i = 0; i < n; i++)
cnt += data[i].maxsize;
oneblock = new char[elemsize * cnt];
cnt = 0;
for (size_t i = 0; i < n; i++)
{
data[i].size = 0;
data[i].col = &oneblock[elemsize * cnt];
cnt += data[i].maxsize;
}
}
size_t BASE_TABLE :: AllocatedElements () const
{
size_t els = 0;
for (size_t i = 0; i < data.Size(); i++)
els += data[i].maxsize;
return els;
}
size_t BASE_TABLE :: UsedElements () const
{
size_t els = 0;
for (size_t i = 0; i < data.Size(); i++)
els += data[i].size;
return els;
}
void BASE_TABLE :: SetElementSizesToMaxSizes ()
{
for (int i = 0; i < data.Size(); i++)
data[i].size = data[i].maxsize;
}
void BASE_TABLE :: DoArchive (Archive & ar, int elemsize)
{
if (ar.Output())
{
size_t entries = 0, size = data.Size();
for (size_t i = 0; i < data.Size(); i++)
entries += data[i].size;
ar & size & entries;
for (size_t i = 0; i < data.Size(); i++)
{
ar & data[i].size;
ar.Do ((unsigned char*)data[i].col, data[i].size*elemsize);
/*
for (size_t j = 0; j < data[i].size*elemsize; j++)
ar & ((unsigned char*) data[i].col)[j];
cout << "write " << data[i].size*elemsize << " chars" << endl;
*/
}
}
else
{
size_t entries, size;
ar & size & entries;
data.SetSize(size);
oneblock = new char [entries*elemsize];
size_t cnt = 0;
for (size_t i = 0; i < size; i++)
{
ar & data[i].size;
data[i].col = oneblock+cnt;
data[i].maxsize = data[i].size;
ar.Do ((unsigned char*)(oneblock+cnt), data[i].size*elemsize);
cnt += data[i].size*elemsize;
}
}
}
}