Reputation: 1441
#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;
Don't think it can be done, have tried every way imaginable.
This code works, as in the program runs, I just can't deallocate the memory. Every time this code is called(not all code included as it isn't relevant) the memory gets bigger. I think that deletion is not happening properly and that the void *
keeps growing.
I have also changed some of the code above based on recommendations here, but as this code is, the memory keeps growing.
Upvotes: 1
Views: 1887
Reputation: 3338
You just want a block of memory that you can pass to some database library routines? Allocate thus:
char * buffer = new char[ len ];
len is the length of the buffer in bytes. To delete, simply do:
delete [] buffer;
You want a void* to pass to a function?
void * DataPtr = static_cast< void* >( buffer );
For extra merit points, use boost to manage deletion:
boost::scoped_array< char > buffer( new char[ len ] );
... then you don't have to worry about deletion. To get the buffer here, you need:
void * DataPtr = static_cast< void* >( buffer.get() );
Upvotes: 0
Reputation: 69988
You should try avoid mixing void*
and new
. In C++ actually, new
is meant to automatically determine the type of the pointer; then why should not use it. At least you can use char*
, if you are simply dealing with raw bytes.
Other point is new void*[SIZE]
allocates void**
. So you should change the declaration to void **DataPtr
. Remove typecasting ahead of new
. You can now delete[] DataPtr;
.
The code have some problems, the variables should be declared like below:
ColLenArray = new long[NumCols * sizeof(long)]; // declare as long[] (not long())
OffsetArray = new long[NumCols * sizeof(long)];
when you declare those variables as, new long()
; it will simply initialize the value and assign a pointer to single long
.
The memory corruption happens because, you are using ColLenArray[i]
, which is accessing wrong memory. Since you are going to use above variables as arrays, it should be new long[]
. Then memory corruption will not happen. After usage, you should delete[]
them.
Upvotes: 1
Reputation: 272517
You can't invoke delete
on a void *
.
The solution is to not cast a pointer-to-void**
(which is what new void*[...]
will give you) to void*
. I don't really know what your code is supposed to be doing, but have you tried changing the type of DataPtr
to void **
?
More generally, avoid void*
as far as possible in C++. There are better solutions. If you edit your question to describe what you're trying to achieve, then we may be able to help suggest something.
Upvotes: 3