Привет, у меня есть кросс-платформенное приложение C++, работающее на Fedora25, которое предсказуемо падает примерно через день выполнения с ошибкой realloc(): недопустимый следующий размер.
Я сузил проблему до определенного pthread, который периодически отправляет обновления подключенным клиентам и очищает очередь исходящих сообщений. Я выделяю место для char * внутри функций, вызываемых потоком, которое освобождаю после отправки. Я обычно не использую C++, поэтому я делаю std::string в фоновом режиме, а затем конвертирую в char *, когда мне это нужно. Я хочу убедиться, что не упустил чего-то простого и каких-либо советов о том, как реструктурировать или исправить это.
static void* MyPThreadFunc(void * params) {
assert(params);
MyAppServer *pAppServer = (MyAppServer *)params;
if(pAppServer != NULL) {
int loopCounter = 1;
char* tempBuf;
int tempBufLen;
int tempDatSetDelay;
while(true) {
for(int i=0; i<pAppServer->GetUpdateDataSetCount();i++) {
tempDatSetDelay = pAppServer->GetDataSetDelay(pAppServer->VecDatSets[i].name);
if(tempDataSetDelay == 1 ||(tempDataSetDelay > 0 && loopCounter % tempDataSetDelay == 0)) {
pAppServer->UpdateDataSetMsgStr(pAppServer->VecDataSets[i]);
tempBuf = (char*)pAppServer->GetDataSetMsgStr(i); //returns const char*
broadcast(pAppServer->Con,mg_mk_str(tempBuf));
delete [] tempBuf;
}//if
} //for
//empty outgoing queue
tempBuf = pAppServer->OUtgoingMsgQueue.peek(tempMsgLen);
while(tempMsgLen>0) {
broadcast(pAppServer->Con,mg_mk_str(tempBuf));
pAppServer->OUtgoingMsgQueue.dequeue();
delete [] tempBuf;
tempBuf = pAppServer->OUtgoingMsgQueue.peek(tempMsgLen);
}
sleep(1);
loopCounter = loopCounter==std::numeric_limits<int>::max() ? 1 : ++loopCounter;
} //while
pAppServer=0;
}
}
const char* AppServer::GetDataSetMsgStr(const int idx) {
pthread_mutex_lock(&mLock);
// Dynamically allocate memory for the returned string
char* ptr = new char[VecDataSets[idx].curUpdateMsg.size() + 1]; // +1 for terminating NUL
// Copy source string in dynamically allocated string buffer
strcpy(ptr, VecDataSets[idx].curUpdateMsg.c_str());
pthread_mutex_unlock(&mLock);
// Return the pointer to the dynamically allocated buffer
return ptr;
}
char* MsgQueue::peek(int &len) {
char* myBuffer = new char[512];
len = 0;
pthread_mutex_lock(&mLock);
if(front==NULL) {
len = -1;
pthread_mutex_unlock(&mLock);
return myBuffer;
}
len = front->len;
strncpy(myBuffer,front->chars,len);
pthread_mutex_unlock(&mLock);
return myBuffer;
}
new[]
илиdelete[]
, а вместо этого использоватьstd::string
во всем коде. Используйтеconst char *
только в тот момент, когда он требуется функции, и этого можно легко добиться с помощью функции-членаc_str()
. У вас также есть это:tempBuf = pAppServer->OUtgoingMsgQueue.peek(tempMsgLen);
, и нет указаний на то, что эта функция использовалаnew[]
для выделения памяти (позже вы вызываетеdelete [] tempBuf
). - person PaulMcKenzie   schedule 06.07.2020front->len > 511
? - person Stephen M. Webb   schedule 06.07.2020peek
вы преждевременно выделяете память, не зная, нужно ли это делать. Затем вы предполагаете, что нужно выделить всего 512 байт, а это может быть не так (как указано в предыдущих комментариях), и, наконец, выделение не защищено мьютексом, поэтому не является потокобезопасным. - person PaulMcKenzie   schedule 06.07.2020nullptr
и не выделять память, если памяти для выделения нет. Вызовdelete[]
для нулевого указателя вполне допустим. Кроме того, вы должны размещать код в вопросе, а не в разделе комментариев. - person PaulMcKenzie   schedule 07.07.2020