c++bufferdynamic-memory-allocationstrtod

Using strtof in a loop to parse numbers from a char buffer


I have a question about allocating and releasing memory.

I want to read a char buffer in a loop and save the float values ​​to a vector. I get the buffer by reading an fstream.

But my approach always crashes when deleting the buffers at the end.

Is it a problem that I change the buffer during my loop? Has anybody an idea how to fix this?

I am thankful for every hint!

char* buffer1 = new char[size]; // the size is given
char* buffer2 = NULL;

fileStream.read(buffer1,size);

while(true)
{
  // read double from buffer
  // and get pointer to the new buffer -> buffer2
  double tempDouble = strtod(buffer1, &buffer2);

  // If nothing has been read (buffer stays the same) -> break
  if (buffer1 == buffer2)   
      break;
  else // change the buffer to read the next double during the next interation step 
      buffer1= buffer2;

  // collect the doubles
  collectedDoubles.push_back(tempDouble);

  // if all numbers are read -> break
  if (++doubleCount == numDoubles) // termination condition
    break;
}

// delete the allocated buffer
delete[] buffer1;

// do I have th delete the 2nd buffer too?
// delete[] buffer2;

Solution

    1. According to the docs of strtod:

      The functions sets the pointer pointed to by str_end to point to the character past the last character interpreted. If str_end is NULL, it is ignored.

      So your pointer buffer2 is still NULL and after you do buffer1= buffer2; - buffer1 now also is NULL (Btw, here is memory leak as the data is lost).

    2. do I have th delete the 2nd buffer too?

      In this case - no, because deleting a NULL pointer is no-operation.

    Solution:

    Take a look at the example provided in docs for strtod function, here is similar according to your code:

    char* buffer1 = new char[size];
    char* buffer2;                           // note no NULL here !
    char* p = buffer1;                       // we'll modify this in loop
    
    for (double tempDouble = std::strtod(p, &buffer2); p != buffer2; tempDouble = std::strtod(p, &buffer2))
    {
        p = buffer2;
        if (errno == ERANGE){                // check if some error occured during attempt to convertion
            std::cout << "range error\n";
            errno = 0;
        }
    
        collectedDoubles.push_back(tempDouble);
    
        if (++doubleCount == numDoubles)     // termination condition
            break;
    }
    
    delete[] buffer1;
    

    Edit 1: Take a look at an elegant and very 'C++ like' solution provided suggested by @JerryCoffin in comments to your question.