472,983 Members | 2,395 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,983 software developers and data experts.

Help converting malloc to new

Hi,
I am new to c++ and I am converting a c program to c++. I changed
malloc call to new and I am getting an exception violation. Here is the
relevant piece of code.

Compiler vc++ 7.0 (.Net 2003)

SQLINTEGER nCols;
SQLINTEGER cbColDataLength;
PBYTE* pColumnData = NULL;

=== C style ====
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
pIndicators = malloc(nCols * sizeof(SQLINTEGER));
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)

=== C++ style ====
pColumnData = new PBYTE [nCols * sizeof(PBYTE)];
pIndicators = new SQLINTEGER [nCols * sizeof(SQLINTEGER)];
pColumnData[nCol] = *(new PBYTE [cbColDataLength])

I tried using my logical understanding of pointers but the compiler
kept throwing me out. So looking at the compiler messsages I got it to
compile by using the above syntax. Please help me in figuring out if
this is correct.

Thanks
Prahalad

Feb 2 '06 #1
13 4568
On 2 Feb 2006 14:51:44 -0800, "ppateel" <pp*****@gmail.com> wrote:
Hi,
I am new to c++ and I am converting a c program to c++. I changed
malloc call to new and I am getting an exception violation. Here is the
relevant piece of code.

Compiler vc++ 7.0 (.Net 2003)

SQLINTEGER nCols;
SQLINTEGER cbColDataLength;
PBYTE* pColumnData = NULL;

=== C style ====
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
pIndicators = malloc(nCols * sizeof(SQLINTEGER));
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)

=== C++ style ====
pColumnData = new PBYTE [nCols * sizeof(PBYTE)];
"new" doesn't need to be told the size of the object being newed.
Therefore, this should be:
pColumnData = new PBYTE [nCols];

You are allocating an array of nCols elements of type PBYTE ... the
size is a given.
pIndicators = new SQLINTEGER [nCols * sizeof(SQLINTEGER)]; pIndicators = new SQLINTEGER [nCols];
pColumnData[nCol] = *(new PBYTE [cbColDataLength])
Oops ... you just dereferenced an uninitialized pointer! Besides, you
have a memory leak here because you lose the pointer returned by
new[]. Also, where is "nCol" defined? If you meant "nCols", you are
writing to the element one past the end of the array you just
allocated.

Otherwise, if it is between 0 and nCols-1, you can write:
pColumnData[nCol] = new PBYTE [cbColDataLength];

"new" returns a PBYTE* anyway, which is what pColumnData contains, so
there is no need to cast it (much less dereference it...???).
I tried using my logical understanding of pointers but the compiler
kept throwing me out. So looking at the compiler messsages I got it to
compile by using the above syntax. Please help me in figuring out if
this is correct.


Just be sure to call "delete []" instead of plain delete or free()
when you need to deallocate the arrays. Actually, you would be much
better off using std::vector<PBYTE> or std::vector<SQLINTEGER> for
your buffers.

--
Bob Hairgrove
No**********@Home.com
Feb 2 '06 #2
[Replying in comp.lang.c++...]

ppateel wrote:
I am new to c++ and I am converting a c program to c++. I changed
malloc call to new and I am getting an exception violation. Here is the
relevant piece of code.

Compiler vc++ 7.0 (.Net 2003)

SQLINTEGER nCols;
SQLINTEGER cbColDataLength;
PBYTE* pColumnData = NULL;

=== C style ====
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
pIndicators = malloc(nCols * sizeof(SQLINTEGER));
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)

=== C++ style ====
pColumnData = new PBYTE [nCols * sizeof(PBYTE)];
Drop the sizeof here. Should simply be

pColumnData = new PBYTE[nCols];
pIndicators = new SQLINTEGER [nCols * sizeof(SQLINTEGER)];
Drop the sizeof here as well. Should simply be

pIndicators = new SQLINTEGER[nCols];
pColumnData[nCol] = *(new PBYTE [cbColDataLength])
This one should probably be

for (int col = 0; col < nCol; ++col)
pColumnData[col] = new BYTE[cbColDataLength];
I tried using my logical understanding of pointers but the compiler
kept throwing me out. So looking at the compiler messsages I got it to
compile by using the above syntax. Please help me in figuring out if
this is correct.


It's not.

The original is unclear without the definitions of 'SQLINTEGER' or
'PBYTE' (at least in 'comp.lang.c++', do not cross-post to two groups
that have different areas of definitions). And the intention of the
allocations is murky, but I think I guessed it close...

V
--
Please remove capital As from my address when replying by mail
Feb 2 '06 #3
ppateel a écrit :
Hi,
I am new to c++ and I am converting a c program to c++. I changed
malloc call to new and I am getting an exception violation. Here is the
relevant piece of code.
IMO, this is not the correct way to convert it to C++.
You have to rethink it completely.


Compiler vc++ 7.0 (.Net 2003)

SQLINTEGER nCols;
SQLINTEGER cbColDataLength;
PBYTE* pColumnData = NULL;
What wonderful all uppercase type names.

=== C style ====
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
That's not C style.
You shouldn't cast malloc() in C.
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)
That's pretty weird, you're casting a void* to a PBYTE here.

=== C++ style ====
pColumnData = new PBYTE [nCols * sizeof(PBYTE)];
The "* sizeof(PBYTE)" shows that you don't know what the new operator
does. It's not a function like malloc().
It is smart enough to know how to get the size of PBYTE by itself.

pColumnData[nCol] = *(new PBYTE [cbColDataLength])


That is strange to me.
Maybe you should point out what you're trying to do.

Feb 2 '06 #4
On Fri, 03 Feb 2006 00:18:45 +0100, loufoque
<lo******@remove.gmail.com> wrote:
ppateel a écrit :
Hi,
I am new to c++ and I am converting a c program to c++. I changed
malloc call to new and I am getting an exception violation. Here is the
relevant piece of code.
IMO, this is not the correct way to convert it to C++.
You have to rethink it completely.


Compiler vc++ 7.0 (.Net 2003)

SQLINTEGER nCols;
SQLINTEGER cbColDataLength;
PBYTE* pColumnData = NULL;


What wonderful all uppercase type names.


They are macros defined in the standard ODBC header files. I think
they are common enough not to get all bent out of shape here, though;
people who ever did any ODBC development are familiar with them.

=== C style ====
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));


That's not C style.
You shouldn't cast malloc() in C.


malloc returns a void*, so you have to cast it if you are compiling
the code in a C++ translation unit.
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)


That's pretty weird, you're casting a void* to a PBYTE here.


Depends on how PBYTE is defined, doesn't it?

=== C++ style ====
pColumnData = new PBYTE [nCols * sizeof(PBYTE)];


The "* sizeof(PBYTE)" shows that you don't know what the new operator
does. It's not a function like malloc().
It is smart enough to know how to get the size of PBYTE by itself.


True.
pColumnData[nCol] = *(new PBYTE [cbColDataLength])
That is strange to me.


Indeed.
Maybe you should point out what you're trying to do.


--
Bob Hairgrove
No**********@Home.com
Feb 2 '06 #5
On Fri, 03 Feb 2006 00:11:47 +0100, Bob Hairgrove
<in*****@bigfoot.com> wrote:
"new" returns a PBYTE* anyway (...)


This should read:

"new PBYTE[]" returns a PBYTE* anyway (...)

--
Bob Hairgrove
No**********@Home.com
Feb 2 '06 #6
Bob,
You are correct. This is part of a dll source code that is being used
as an extended stored procedure in SQL Server. The main function is to
connect to a IBM Mainframe using a third part ODBC driver. The reason
for converting it to C++ is to get the advantage of structured error
handling. The c code was getting an access violation and bringing the
SQLServer down. So I thought of moving it to C++ and trap the AV and
exit gracefully. It is a different issue that I am AVing at a different
location but atleast I exit gracefully without affecting the SQLServer.
If it is necessary I am more than happy to post the C source.
Now coming to what the dll does. It uses ODS library to connect to
the datasource and gets a resultset. Then it allocates an array of
pointers to the columns. there are nCols number of coulmns That is the
line

=== C code ====
// There are nCols number of columns so we have to allocate memory
to hold
// pointers to each column each of the size occupied by PBYTE.

pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
pIndicators = malloc(nCols * sizeof(SQLINTEGER));
==============

here is more info on PBYTE , nCols

typedef unsigned char *PBYTE;
SQLSMALLINT nCols;
typedef short SQLSMALLINT;

After that there are call to ODBC functions to get the column
definations then we allocate memory for holding the rows

==== C code =======
// Allocate memory for row data.
if ((pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)) ==
NULL)
{
srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0,
0);
goto SAFE_EXIT;
}

// Set all the allocated memory to 0 thus
//initializing the entire allocated memory
memset(pColumnData[nCol], 0, cbColDataLength);
================================================== ====
once the memory is allocated for the rows then another call to ODBC
function to get the row and store the data in the above allocated
memory. Then more logic to move the data from there to SQL Server
structures.
Hopefully I was lucid enough. If not I will try to answer any other
question. As I said if you want I will copy the C code. It is not
really big. The whole thing is less than 800 lines. I did not want to
make this post really big.

Thanks for the quick response. Hope fully I will be able to put this to
rest from all you help.

Prahalad

Feb 3 '06 #7

"ppateel" <pp*****@gmail.com> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com...
Bob,
You are correct. This is part of a dll source code that is being used
as an extended stored procedure in SQL Server. The main function is to
connect to a IBM Mainframe using a third part ODBC driver. The reason
for converting it to C++ is to get the advantage of structured error
handling. The c code was getting an access violation and bringing the
SQLServer down. So I thought of moving it to C++ and trap the AV and
exit gracefully. It is a different issue that I am AVing at a different
location but atleast I exit gracefully without affecting the SQLServer.
If it is necessary I am more than happy to post the C source.
Now coming to what the dll does. It uses ODS library to connect to
the datasource and gets a resultset. Then it allocates an array of
pointers to the columns. there are nCols number of coulmns That is the
line

=== C code ====
// There are nCols number of columns so we have to allocate memory
to hold
// pointers to each column each of the size occupied by PBYTE.

pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
pIndicators = malloc(nCols * sizeof(SQLINTEGER));
==============

here is more info on PBYTE , nCols

typedef unsigned char *PBYTE;
SQLSMALLINT nCols;
typedef short SQLSMALLINT;

After that there are call to ODBC functions to get the column
definations then we allocate memory for holding the rows

==== C code =======
// Allocate memory for row data.
if ((pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)) ==
NULL)
{
srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0,
0);
goto SAFE_EXIT;
}

// Set all the allocated memory to 0 thus
//initializing the entire allocated memory
memset(pColumnData[nCol], 0, cbColDataLength);
================================================== ====
once the memory is allocated for the rows then another call to ODBC
function to get the row and store the data in the above allocated
memory. Then more logic to move the data from there to SQL Server
structures.
Hopefully I was lucid enough. If not I will try to answer any other
question. As I said if you want I will copy the C code. It is not
really big. The whole thing is less than 800 lines. I did not want to
make this post really big.

Thanks for the quick response. Hope fully I will be able to put this to
rest from all you help.

Prahalad
Actually, your question has been answered.

malloc requires as a parameter the number of bytes to allocate.
new[] requires the number of elements.

MyStructure* MyArray = malloc( 10 * sizeof(MyClass) ); // Number of bytes.
MyClass* MyArray = new MyClass[10]; // Number of elements.

So, in your specific cases (presuming everything else is correct):
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE)); pColumnData = new PBYTE[nCols];
pIndicators = malloc(nCols * sizeof(SQLINTEGER));

pIndicators = new SQLINTEGER[nCols];

remember to use
delete[] pColumnData;
delete[] pIndicators;

when you're done with them.

Is this clear?
Feb 3 '06 #8
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.

Feb 3 '06 #9
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
Feb 3 '06 #10
In article <11**********************@g49g2000cwa.googlegroups .com>,
"ppateel" <pp*****@gmail.com> wrote:
Hi,
I am new to c++ and I am converting a c program to c++. I changed
malloc call to new and I am getting an exception violation. Here is the
relevant piece of code.

Compiler vc++ 7.0 (.Net 2003)

SQLINTEGER nCols;
SQLINTEGER cbColDataLength;
PBYTE* pColumnData = NULL;

=== C style ====
pColumnData = (PBYTE*) malloc(nCols * sizeof(PBYTE));
pIndicators = malloc(nCols * sizeof(SQLINTEGER));
pColumnData[nCol] = (PBYTE) malloc(cbColDataLength)

=== C++ style ====
pColumnData = new PBYTE [nCols * sizeof(PBYTE)];
pIndicators = new SQLINTEGER [nCols * sizeof(SQLINTEGER)];
pColumnData[nCol] = *(new PBYTE [cbColDataLength])

I tried using my logical understanding of pointers but the compiler
kept throwing me out. So looking at the compiler messsages I got it to
compile by using the above syntax. Please help me in figuring out if
this is correct.

Thanks
Prahalad


Don't change the C code from malloc to new, there is no reason to...

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Feb 3 '06 #11
Bob,
First thanks for all the help. You really dont know how much I
appreciate it ! But I still have not grasped all the details.
If you have the time, it's probably worth it to
write little wrapper classes which take care of these details for you.


That was the idea I started when I started writing this dll. This is a
general puprpose dll for sqlserver.Something like a SQL command line
interface. the user can type in any sql statement and the dll executes
the statement using SQLExecDirect. So I will not know neither the
number of columns nor the type of columns nor the number of rows. My
logic for handling the situation

call SQLNumResultCols

get number of columns
allocate array pointers to hold column data and the null indicators
(pColumnData = new PBYTE [nCols];
pIndicators = new SQLINTEGER [nCols]; )

for each column
cal SQLColAttribute to get column details (name, type, length etc)
allocate memory of column type and column length to hold data
call SQLBindCol to bind each column to the above memory location
call srv_describe to set up the column in sqlserver
next

do until no more rows
call SQLFetch
(this puts the data of each column in the memory location)
for each column
call srv_describe to set data in SQLServer
next
call srv_sendrow (to send the row to sql server)
next

do cleanup (release odbc resources, allocated memory)
call srv_sendrow with a SRV_DONE_MORE | SRV_DONE_COUNT
return

I have to figure out the whole std::vector<BYTE> (or
std::vector<unsigned
char>) concept as I am still a newbie when it comes to C++

Feb 3 '06 #12
Bob Hairgrove a écrit :
malloc returns a void*, so you have to cast it if you are compiling
the code in a C++ translation unit.


C code should be compiled with a C compiler.
And there are good reasons not to cast malloc.
http://www.cpax.org.uk/prg/writings/casting.php
Feb 4 '06 #13
Just an update. I finally was able to solve this issue. Thanks for
everybody in helping me understand the finer difference between malloc
and new especially Bob Hairgrove for providing more insight into ODBC
API .

Thanks
Prahalad

Feb 9 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: laclac01 | last post by:
I have developed my own copy function for coping my own dynamic memory structure. It works, but I feel its not too efficient. There must be a quicker way to copy the data. In some of the...
4
by: Tarique Jawed | last post by:
Alright I needed some help regarding a removal of a binary search tree. Yes its for a class, and yes I have tried working on it on my own, so no patronizing please. I have most of the code working,...
3
by: Robert Rota | last post by:
Need help figuring out why my program core dumps and if I have the structures right. If you are interested in helping me I can send you a copy of the code. The program is supposed to mimic a 3...
27
by: MK | last post by:
I am a newbie. Please help. The following warning is issued by gcc-3.2.2 compiler (pc Linux): ================================================================== read_raw_data.c:51: warning:...
6
by: TC | last post by:
Hi. I write a program in c language that read a text file and extrapolate the word. for all word the program calculate the number of the times that word is present in the text. The problem is the...
21
by: c | last post by:
Hi everybody. I'm working on converting a program wriiten on perl to C, and facing a problem with concatenate strings. Now here is a small program that descripe the problem, if you help me to...
156
by: Lame Duck | last post by:
Hi Group! I have a vector<floatvariable that I need to pass to a function, but the function takes a float * arguement. That's OK, I can convert by doing &MyVector.front(), but when I get back a...
0
by: shrik | last post by:
I have following error : Total giant files in replay configuration file are : File name : /new_file/prob1.rec Given file /new_file/prob1.rec is successfully verified. Splitting for giant file...
19
by: mdh | last post by:
I am trying to define a struct called temp, using this code. Please be kind in explaining with this is not working :-) #include <stdio.h> #include <stdlib.h> struct t_node_n{ char *word;...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.