2017-02-03 18 views
0

У меня вопрос о распределении и освобождении памяти.Использование strtof в цикле для разбора чисел из буфера символов

Я хочу прочитать буфер символов в цикле и сохранить значения float в вектор. Я получаю буфер, читая fstream.

Но мой подход всегда сбой при удалении буферов в конце.

Проблема в том, что я меняю буфер во время цикла? Есть ли у кого-нибудь идея, как это исправить?

Я благодарен за каждый намек!

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; 
+2

'станд :: копия (станд :: istream_iterator (FileStream), станд :: istream_iterator (), станд :: back_inserter (collectedDoubles));' –

+0

Вам не нужно удалять Буфер2. Вы можете посмотреть здесь пример http://en.cppreference.com/w/cpp/string/byte/strtof – Shaana

ответ

1
  1. Согласно документации по strtod:

    функции устанавливает указатель указывает str_end, чтобы указать на характер мимо последнего символа истолковано. Если str_end имеет значение NULL, оно игнорируется.

    Так что ваш указатель buffer2 еще NULL и после того, как вы buffer1= buffer2; - buffer1 теперь также является NULL (Кстати, здесь утечка памяти, как данные будут потеряны).

  2. У меня есть удаление второго буфера?

    В этом случае - нет, потому что удаление указателя NULL не работает.

Решение:

Посмотрите на пример, представленной в документации для strtod функции, здесь сходна по вашему коду:

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: Берут посмотрите на изящное и очень «C++ подобное» решение, предложенное @JerryCoffin в комментариях к вашему вопросу.