[Rcpp-devel] ColDatum constructors memory safety

Alistair Gee alistair.gee at gmail.com
Sat Mar 13 00:15:35 CET 2010


The ColDatum default constructor does not initialize any fields except
for "level". But the ColDatum *copy* constructor expects the "type"
field to be properly initialized, b/c if type is COLTYPE_FACTOR, the
copy constructor proceeds to allocate memory using the numLevels field
(which is unreliable b/c numLevels was never initialized). See
comments in source below:

ColDatum::ColDatum() : level(0) { };

ColDatum::ColDatum(const ColDatum& datum) {
  // Need deep copy so contruction/destruction is synchronized.
  s = datum.s;
  x = datum.x;
  i = datum.i;
  type = datum.type;                // XXX datum.type was never initialized.
  level = datum.level;
  numLevels = datum.numLevels; // XXX datum.numLevels was never initialzed.
  d = datum.d;
  if (type == COLTYPE_FACTOR) {
      levelNames = new std::string[numLevels];   // XXX numLevels was copied

// from datum.numLevels which

// was never initialized
      for (int j = 0; j < numLevels; j++)
          levelNames[j] = datum.levelNames[j];     // XXX datum.levelNames is

// an uninitialized pointer.
  }
}

This is a problem if one tries to create a vector of ColDatum, e.g.

vector<ColDatum> colDatumVector(10);

Here, the default constructor is used to first construct a ColDatum
object (which will not have "type" and "levelNames" properly
initialized). Then the copy constructor called by the vector
constructor to create 10 copies.


More information about the Rcpp-devel mailing list