On 3 Feb 2006 01:55:09 -0800, "ppateel" <pp*****@gmail.com> wrote:
Jim
This was more in reply to this<snip>
True.
pColumnData[nCol] = *(new PBYTE [cbColDataLength])
That is strange to me.
ndeed.Maybe you should point out what you're trying to do.
Thanks for clarifying the difference between malloc and new. I know
now that
pColumnData = new PBYTE[nCols];
will give me an array of nCols each element holding a pointer to
PBYTE.
But I am stumped about
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)
If my understanding is correct, here pColumnData is an array to hold
the pointers which point to actual data in the returned columns. And in
the above statement it is allocating memory depending on the size of
each column and storing that pointer in the array elements. Then
another ODBC call will then fill that memory location with the actual
data.
For example if there are 2 columns one a char(10) and another an
integer, then in the C code the first element in pColumnData would hold
a pointer to char(10) value and the second element will hold a pointer
to an integer. In C you would findout what is the length of the each
column and set the cbColumnLength to that value and then do a malloc
and assign the address to element. Since the elements in the column
array point to different types of data I have a vague feeling that I
should be dealing with an array of void pointers and then assign
pointers of appropriate type to each of the elements. Right now I get
the feeling that my conversions to "new" are not functionally the same
as that of malloc.
Prahalad.
You are right. It's been a while since I did any ODBC, but it looks
like you are setting up one buffer for each column and calling
SQLBindColumn.
Here's a better way: calculate how many bytes you need for each column
and round up the numbers to the nearest multiples of whatever the
cache line size is on your machine. On x86 platforms, this is
typically 32. This will help to ensure that you have a minimum of
cache misses when reading and writing the data. Add up the resulting
lengths for all the columns, saving them somewhere so that you know
which element starts a new column. Allocate just one buffer for ALL
the columns by using std::vector<BYTE> (or std::vector<unsigned
char>)...you won't have to worry about new[] and delete[] if you do it
this way. Just make sure that you know when the vector gets destroyed.
If an exception occurs, and your vector is a class member, it will get
destroyed when the class is destroyed. Store the address to the first
element of each range of bytes in pColumnData[].
You will have to cast these pointers eventually when you get around to
reading and writing the data in C++, but that's unavoidable with
ODBC's C interface. If you have the time, it's probably worth it to
write little wrapper classes which take care of these details for you.
--
Bob Hairgrove
No**********@Home.com