Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Visual C++ / MFC / WTL > Динамический массив и WinInet


Автор: devmstr 06.06.06, 14:15
Создаю динамический массив. Передаю его используя WSASend. Потом пытаюсь его освободить делая delete[] st; и ничего. Ошибка.
В чем юмор. Мне не жалко в данном месте можно и статический. Но просто интерестно. Тем более что статический не везде покатит.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    //Forming head of send string
    BOOL  FormString(DWORD nFlSize, char* cRz, int* nRz)
    {
        memset(cRz, '0', FLSIZESTRLEN);
        static char cTmp[FLSIZESTRLEN];
        itoa(nFlSize, cTmp, 10);
        static int nStr = strlen(cTmp);
        for (int it = 1; (nStr - it)>= 0; it++)
            cRz[FLSIZESTRLEN - it] = cTmp[strlen(cTmp) - it];
        cRz[FLSIZESTRLEN] = 0;
     
        char st[255];
        sprintf(st, "#%s#%s%s#",CONTRCODE, SENDSCRSHOT, cRz);
        strcpy(cRz, st);
        return TRUE;
    }
     
    BOOL SendScreenShort(SOCKET socket)
    {
            
        char st = new char[STRMAX];
     
        WSABUF wsaBuf;  
        INT    iSz;                             //Size of Jpeg buffer
        DWORD  nSend;                           //Bytes was send
        LPVOID bfImg =  MakeScreenShort(&iSz);  //Receive Jpeg Buffer
     
        FormString(iSz, st, NULL);
        
        wsaBuf.buf  = st;
        wsaBuf.len  = strlen(st);
        
        if (WSASend(socket, &wsaBuf, 1, &nSend, 0, NULL, NULL))
        {
            int iErr = WSAGetLastError();
            if (iErr == WSAENOBUFS)
            {
                MessageBox(NULL, "Send Error; The Windows Sockets provider reports a buffer deadlock.", "ERROR", MB_ICONERROR);
                return FALSE;
            }
        }
        wsaBuf.buf = (CHAR*)bfImg;
        wsaBuf.len = iSz;
        if (WSASend(socket, &wsaBuf, 1, &nSend, 0, NULL, NULL))
        {
            int iErr = WSAGetLastError();
            if (iErr == WSAENOBUFS)
            {
                MessageBox(NULL, "Send Error; The Windows Sockets provider reports a buffer deadlock.", "ERROR", MB_ICONERROR);
                return FALSE;
            }
        }
        wsaBuf.buf = NULL;
        delete[] st;                //Exception
     
        return TRUE;
    }

Чувствую я где-то сильно затупил.

Автор: LuckLess 06.06.06, 14:17
char st = new char[STRMAX];
замени на
char* st = new char[STRMAX];

Автор: devmstr 06.06.06, 14:18
Это очепятка. Там со звездочкой.

Автор: LuckLess 06.06.06, 14:20
какой ексепшон?
С++ или SEH?
посмотри отладчиком, что происходит с указателем

Автор: devmstr 06.06.06, 14:24
st вроде нормальный. не мусор.
вылетаетна строчке
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    _free_dbg( pUserData, pHead->nBlockUse );


Expression _CrtIsValidHeapPointer(pUserData) - dbgheap.c.



Цитата LuckLess @
SEH

А что это?

Автор: LuckLess 06.06.06, 14:28
Цитата devmstr @
_CrtIsValidHeapPointer

Цитата devmstr @
Цитата (LuckLess @ Сегодня, 17:20)
SEH
А что это?

Виндовые (Structured Exception Handling) исключения.
всеже указатель становаиться невалидным, в какойто момент.

используя CrtIsValidHeapPointer проверяй его на валидность.
и найди то место, в котором он становиться невалидным.

Автор: cozzzy 06.06.06, 14:46
Цитата devmstr @
Создаю динамический массив.

Лучше использовать vector<unsigned char>
И проблем с памятью не будет

Автор: UncleBob 06.06.06, 14:48
devmstr,

Где-то затираешь буфер свой.

На первый взгляд, тут неясность - создаешь буфер длиной STRMAX, а нулишь его по размеру FLSIZESTRLEN, ну и дальше там везде FLSIZESTRLEN...

Потом... nStr = strlen(cTmp); Допустим, nStr 25, а FLSIZESTRLEN 20... Получится, что пишешь по отрицательным индексам в буфер. А там сишный рантайм хранит свою инфу (pHead->nBlockUse это как раз ее проверка)

Нельзя так с буферами работать... В лучшем случае экспшен, в худшем - уязвимость, а уязвимость + Винсок = троян.

Автор: Ace 06.06.06, 17:47
devmstr, зачем тебе такое извращение в FormString?
Там всё это можно записать в одну строчку:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    BOOL  FormString(DWORD nFlSize, char* cRz, int* nRz)
    {
        sprintf( cRz, "#%s#%s%*u#",CONTRCODE, SENDSCRSHOT, FLSIZESTRLEN, nFlSize);
        return TRUE;
    }

Если я правильно понял, и FLSIZESTRLEN у тебя означает длину поля для размера. Да и функция собсна получается нафих не нужна :lol:
ЗЫ. А вообще, на будущее - это считается плохим стилем, писать функцию, в которой происходит запись в память без ограничения...

Автор: arcsupport 06.06.06, 22:01
А нулевой байт в строке учитывали?

Автор: devmstr 07.06.06, 01:27
Ace
Мне просто нужно было, что бы число было обязательно длиной в 8 байт. Но это помойму можно тоде реализовать с помощью sprintf. :)

Всем спасибо. Глюк нашел. На будущее постараюсь писать по аккуратнее.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)