Как мне удалить этот указатель Void? - PullRequest
1 голос
/ 09 мая 2011
#define ALIGNBUF(Length) Length % ALIGNSIZE ? \
              Length + ALIGNSIZE - (Length % ALIGNSIZE) : Length 

short NumCols;
long * ColLenArray, * OffsetArray;

ColLenArray = new long(NumCols * sizeof(long));
OffsetArray = new long(NumCols * sizeof(long));

// THIS CODE SHOULD NOT BE NEEDED TO UNDERSTAND THE PROBLEM
// BUT I HAVE INCLUDED IT JUST IN CASE
////////////////////////////////////////////////////////////
SQLColAttribute(hstmt, ((SQLUSMALLINT) i)+1, SQL_DESC_OCTET_LENGTH, NULL, 0, NULL, &ColLenArray[i]);
    ColLenArray[i] = ALIGNBUF(ColLenArray[i]);
    if (i)
        OffsetArray[i] = OffsetArray[i-1]+ColLenArray[i-1]+ALIGNBUF(sizeof(SQLINTEGER));
////////////////////////////////////////////////////////////

void **DataPtr = new void*[OffsetArray[NumCols - 1] + ColLenArray[NumCols - 1] + ALIGNBUF(sizeof(long))];

delete []DataPtr;

Не думай, что это можно сделать, старался всеми возможными способами.

Этот код работает, так как в программе выполняется, я просто не могу освободить память. Каждый раз, когда этот код вызывается (не весь код включен, так как он не актуален), память увеличивается. Я думаю, что удаление не происходит должным образом и что void * продолжает расти.

Я также изменил некоторые из приведенного выше кода на основе рекомендаций, приведенных здесь, но, поскольку этот код, память продолжает расти.

Ответы [ 3 ]

3 голосов
/ 09 мая 2011

Вы не можете вызвать delete на void *.

Решение состоит в том, чтобы не приводить указатель на void** (что даст вам new void*[...]) на void*. Я действительно не знаю, что должен делать ваш код, но вы пытались изменить тип DataPtr на void **?

В общем, избегайте, насколько это возможно, void* в C ++. Существуют лучшие решения. Если вы отредактируете свой вопрос, чтобы описать, чего вы пытаетесь достичь, мы сможем вам что-то предложить.

1 голос
/ 09 мая 2011

Вам следует избегать смешивания void* и new.На самом деле в C ++ new предназначен для автоматического определения типа указателя;тогда почему бы не использовать его.По крайней мере, вы можете использовать char*, если вы просто имеете дело с необработанными байтами.

Другой пункт - new void*[SIZE], выделяет void**.Таким образом, вы должны изменить объявление на void **DataPtr.Удалите приведение типов перед new.Теперь вы можете delete[] DataPtr;.

Редактировать:

Код имеет некоторые проблемы, переменные должны быть объявлены, как показано ниже:

ColLenArray = new long[NumCols * sizeof(long)]; // declare as long[] (not long())
OffsetArray = new long[NumCols * sizeof(long)];

, когда вы объявляете эти переменные какnew long();он просто инициализирует значение и назначит указатель на single long.

Повреждение памяти происходит из-за того, что вы используете ColLenArray[i], который обращается к неправильной памяти.Поскольку вы собираетесь использовать указанные выше переменные в качестве массивов, оно должно быть new long[].Тогда повреждения памяти не произойдет.После использования вы должны delete[] их.

0 голосов
/ 09 мая 2011

Вам просто нужен блок памяти, который вы можете передать некоторым подпрограммам библиотеки базы данных?Распределите таким образом:

char * buffer = new char[ len ];

len - длина буфера в байтах.Чтобы удалить, просто выполните:

delete [] buffer;

Вы хотите, чтобы void * передавался в функцию?

void * DataPtr = static_cast< void* >( buffer );

Для дополнительных заслуг используйте повышение для управления удалением:

boost::scoped_array< char > buffer( new char[ len ] );

... тогда вам не нужно беспокоиться об удалении.Чтобы получить здесь буфер, вам нужно:

void * DataPtr = static_cast< void* >( buffer.get() );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...