Symbian паникует при удалении динамического массива - PullRequest
0 голосов
/ 20 августа 2009

Я пытаюсь выделить массив символов размером 1000. Этот массив передается в функцию, где она должна быть заполнена данными это было получено от сокета TCP. Проблема возникает затем, когда я пытаюсь удалить буфер []: здесь я получаю в результате пользователя Паника 42. К сожалению, я не очень понимаю, что происходит не так в этом простом коде fragement ...

int main
{
    unsigned char *buffer = new unsigned char[1000];
    Recv(&buffer);

    delete[] buffer;        
    return (0);
}

void Recv(unsigned char **buffer)   
{
    TRequestStatus iStatus;
    TSockXfrLength len;

    TBuf8<1000> buff;
    iSocket.RecvOneOrMore( buff, 0, iStatus, len );     
    User::WaitForRequest(iStatus);  

    *buffer = ( unsigned char* )buff.Ptr();  
}   

Спасибо за любые полезные советы!

Ответы [ 3 ]

5 голосов
/ 20 августа 2009

То, что говорит Конрад, правда, но я не думаю, что он знает Symbian. Если вам нужна функция для чтения байтов в буфер символов, то лучшим решением будет:

void Recv(unsigned char *aBuffer, int aSize)   
{
    TRequestStatus iStatus;
    TSockXfrLength len;

    TPtr8 buff(aBuffer, aSize);
    iSocket.RecvOneOrMore( buff, 0, iStatus, len );         
    User::WaitForRequest(iStatus);  
}

TBuf8 - дескриптор, который содержит массив для хранения данных. TPtr8 - это дескриптор, который ссылается на указанный вами внешний буфер. Любой из них может быть передан в RecvOneOrMore, так как они оба наследуются от типа параметра, TDes8 &. Таким образом, сокет можно сделать так, чтобы записывать свои данные непосредственно в буфер, вместо записи в буфер в стеке, а затем копировать, как это делает код Конрада.

Вам, вероятно, также необходимо проверить состояние, чтобы обнаружить ошибки, и сообщить об успехе / неудаче и продолжительности записи обратно вызывающей стороне.

2 голосов
/ 20 августа 2009

Ваше распределение массива не имеет никакого эффекта, потому что внутри функции вы назначаете новый указатель на массив:

*buffer = ( unsigned char* )buff.Ptr();

Теперь буфер указывает на другую область памяти, предположительно ту, которую вы не можете освободить, используя delete (например, одну в стеке, или выделенную, используя что-то, отличное от new).

Чтобы решить эту проблему, лучше всего скопировать данные в ваш массив:

void Recv(unsigned char *buffer)   
{
    TRequestStatus iStatus;
    TSockXfrLength len;

    TBuf8<1000> buff;
    iSocket.RecvOneOrMore( buff, 0, iStatus, len );         
    User::WaitForRequest(iStatus);  

    unsigned char* const tmpbuf = static_cast<char*>(buff.Ptr());
    std::copy(tmpbuf, tmpbuf + len, buffer);
}

Обратите внимание, что указатель buffer теперь передается непосредственно в функцию Recv, дальнейшее косвенное обращение не требуется, поскольку мы не манипулируем указателем напрямую.

0 голосов
/ 20 августа 2009

Хм, вы пытаетесь удалить [] то, что не выделено вами. Вы удаляете [] ing buff.Ptr () при утечке массива, выделенного в main ().

...