Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > C equivalent of C++ new()?

Reply
Thread Tools

C equivalent of C++ new()?

 
 
Ben Bacarisse
Guest
Posts: n/a
 
      10-14-2010
Steve555 <> writes:
> Steve555 <> writes:

<snip>
>> Thanks, but in case I didn't explain well enough, the crucial point is
>> that I need pointers:
>>
>> double a = myStructArray[1]->a;
>>
>> I'm passing large structures by pointer to time-critical functions to
>> save the overhead of copying.

>
> MyStruct **myStructArray;


If you are going to tag names with type info, it's wise to be clear.
This is an array of pointers not an array of structures.

> myStructArray = (MyStruct*)malloc(1024 * sizeof(MyStruct*))
> for(long i=0; i<1024; i++){


long? If you might have very large arrays, the C type to use is
size_t. Note that it is an unsigned type.

> myStructArray[i] = malloc(sizeof(MyStruct));
> myStructArray[i]->g = i;
> }
> printf("%d", myStructArray[123]->g);


Do you need all the pointers to be "independent"? Another common patter
is to allocate a single array of structs and to point into that array.
You get two rather than 1025 malloc calls and only two pointers to free.

MyStruct *tmp_array = malloc(1024 * sizeof *tmp_array);
MyStruct **myStructPtrArray = malloc(1024 * sizeof *myStructPtrArray);
for (size_t i = 0; i < 1024; i++)
myStructPtrArray[i] = &tmp_array[i];

Of course, this only works in some situations. If the pointers get
handed off to other functions and data structures that might want to
free them individually you can't use this structure.

--
Ben.
 
Reply With Quote
 
 
 
 
John Bode
Guest
Posts: n/a
 
      10-14-2010
On Oct 14, 1:35*am, Steve555 <foursh...@btinternet.com> wrote:
> Hi
>
> I've been working with C++ and Objective-C and I've forgotten how to
> allocate memory for an array of structs in C.
>
> Given a struct:
>
> typedef struct {
> * * double * a,b,c,d;
> * * long * * * e,f,g,h;
>
> } MyStruct
>
> I want to do the equivalent of :
>
> MyStruct * **myStructArray;
> myStructArray = new MyStruct*[1024];
> for(long i=0; i<1024; i++){
> * * myStructArray[i] = new MyStruct;}
>


Since you're doing a two-step allocation and deallocation, it might be
best to create separate allocation and deallocation functions; that
will help keep everything organized.

MyStruct **createArray(size_t arraySize)
{
// sizeof *theArray == sizeof (MyStruct *)
MyStruct **theArray = malloc(sizeof *theArray * arraySize);
if (theArray)
{
size_t i;
for (i = 0; i < arraySize; i++)
{
// sizeof *theArray[i] == sizeof (MyStruct)
theArray[i] = malloc(sizeof *theArray[i]);
if (!theArray[i])
break;

/* initialize theArray[i] here */
}

if (i < arraySize)
{
/**
* One of the allocations failed; release everything
* allocated so far.
*/
size_t j;
for (j = 0; j < i; j++)
free(theArray[j]);

free(theArray);
theArray = NULL;
}
}
return theArray;
}

void destroyArray(MyStruct ***theArray, size_t arraySize)
{
size_t i;
for (i = 0; i < arraySize; i++)
free((*theArray)[i];
free(*theArray);
*theArray = NULL;
}

int main(void)
{
MyStruct **myArray = createArray(1024);
/**
* do stuff with myArray
*/
destroyArray(&myArray);
...
}
 
Reply With Quote
 
 
 
 
Fred
Guest
Posts: n/a
 
      10-14-2010
On Oct 14, 6:12*am, lawrence.jo...@siemens.com wrote:
> Steve555 <foursh...@btinternet.com> wrote:
>
> > MyStruct * **myStructArray;
> > myStructArray = (MyStruct*)malloc(1024 * sizeof(MyStruct*))
> > for(long i=0; i<1024; i++){
> > * * myStructArray[i] = malloc(sizeof(MyStruct));
> > * * myStructArray[i]->g = i;
> > }
> > printf("%d", myStructArray[123]->g);

>
> > OK, well that *seems* to work, but as with all memory problems, I
> > might just have got lucky.

>
> That works, but it's rather inefficient. *You can allocate all the
> structs in a single block instead:
>
> * * * * MyStruct *myStructArray = malloc(1024 * sizeof *myStructArray);
> * * * * for (int i = 0; i < 1024; i++) {
> * * * * * *myStructArray[i].g = i;
> * * * * }
> * * * * printf("%d\n", myStructArray[123].g;
>
> If you need pointers, use the "&" operator:
>
> * * * * myFunc(&myStructArray[42]);
> --
> Larry Jones
>
> Wow, how existential can you get? -- Hobbes


Better to use sizeof(*myStructArray). That is,
Type *instance;
instance = malloc( n * sizeof(*instance) );

that way if you ever change Type, you don't need to find
and change all of the malloc/calloc/realloc lines.

And don't forget to #include <stdlib.h>

--
Fred K
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      10-14-2010
On 2010-10-14, Steve555 <> wrote:
> myStructArray = (MyStruct*)malloc(1024 * sizeof(MyStruct*))
> for(long i=0; i<1024; i++){
> myStructArray[i] = malloc(sizeof(MyStruct));
> }


This can't be correct. Not seeing the declaration of myStructArray, I
can't be sure what's wrong with it, but it should be either:
myStruct *myStructArray;
myStruct init_values = { 0, 3, 21 }; /* or whatever */
myStructArray = malloc(1024 * sizeof(MyStruct));
for (int i = 0; i < 1024; ++i) {
myStructArray[i] = init_values;
}
or
myStruct **myStructArray;
myStruct init_values = { 0, 3, 21 }; /* or whatever */
myStructArray = malloc(1024 * sizeof(MyStruct *));
for (int i = 0; i < 1024; ++i) {
myStructArray[i] = malloc(sizeof(MyStruct));
*myStructArray[i] = init_values;
}

Usually, in C, you'd do the first. You're thinking like a C++ programmer,
and that's led you to two mistakes:

1. You're trying to allocate all the items separately, because you're
thinking of allocation/new as where the constructor happens. There's
no constructor! Just populate the items directly. Each element of
the array should, usually, be a myStruct, not a pointer.
2. You're casting the return from malloc. Don't do that; it's bad style
in C. (In C++, there are perhaps sound reasons for void * not to
automatically convert; in C, there aren't, so it converts automatically.
Casting pointer conversions like this just hides bugs.)

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      10-14-2010
On 2010-10-14, Steve555 <> wrote:
> Thanks, but in case I didn't explain well enough, the crucial point is
> that I need pointers:


> double a = myStructArray[1]->a;


> I'm passing large structures by pointer to time-critical functions to
> save the overhead of copying.


That doesn't mean you need separately-allocated objects.

function(&myStructArray[1]);

You can take the address of the objects in the array regardless, and
if you're worried about time-critical, extra allocations are probably
bad.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      10-14-2010
On 2010-10-14, Steve555 <> wrote:
> MyStruct **myStructArray;
> myStructArray = (MyStruct*)malloc(1024 * sizeof(MyStruct*))


This cast is obviously wrong, but also unnecessary.

> for(long i=0; i<1024; i++){
> myStructArray[i] = malloc(sizeof(MyStruct));
> myStructArray[i]->g = i;
> }
> printf("%d", myStructArray[123]->g);


This is otherwise correct.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Paul N
Guest
Posts: n/a
 
      10-14-2010
On 14 Oct, 07:52, Steve555 <foursh...@btinternet.com> wrote:
> Thanks, I wasn't sure if that was the case.
> But I still can't get my head around the fact it's pointers of
> pointers:
>
> Would this be correct, based on what you said:
>
> myStructArray = (MyStruct*)malloc(1024 * sizeof(MyStruct*))
> for(long i=0; i<1024; i++){
> * * myStructArray[i] = malloc(sizeof(MyStruct));
> }


That looks right, though there are useful comments elsewhere in the
thread, including checking the return value of malloc and using a
size_t for i.

If it's any consolation, I found the C syntax odd when I first used
it. You reserve space for a MyStruct and then you pretend you have one
there. It seemed a bit like building a tiger cage and then expecting a
tiger to magically appear in it. But, if you think about it, there is
nothing further you need to do to summon a MyStruct into existence.
Possibly you need to initialise the space in some way, just like a
constructor in C++ except that you need to call it yourself.

The C++ syntax seems more intuitive - you want a new MyStruct, so you
ask for one and you get one.

Hope that helps, or at least reassures!
Paul.
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      10-30-2010
On 30 Oct, 22:01, "Scouser" <sco...@scouse-no-spam.com> wrote:
> "Seebs" <usenet-nos...@seebs.net> wrote in message
>
> news:slrnibeidt.fc7.usenet-...
>
>
>
>
>
>
>
> > This can't be correct. *Not seeing the declaration of myStructArray, I
> > can't be sure what's wrong with it, but it should be either:
> > myStruct *myStructArray;
> > myStruct init_values = { 0, 3, 21 }; /* or whatever */
> > myStructArray = malloc(1024 * sizeof(MyStruct));
> > for (int i = 0; i < 1024; ++i) {
> > myStructArray[i] = init_values;
> > }
> > or
> > myStruct **myStructArray;
> > myStruct init_values = { 0, 3, 21 }; /* or whatever */
> > myStructArray = malloc(1024 * sizeof(MyStruct *));
> > for (int i = 0; i < 1024; ++i) {
> > myStructArray[i] = malloc(sizeof(MyStruct));
> > *myStructArray[i] = init_values;
> > }

>
> > Usually, in C, you'd do the first. *You're thinking like a C++ programmer,
> > and that's led you to two mistakes:

>
> > 1. *You're trying to allocate all the items separately, because you're
> > thinking of allocation/new as where the constructor happens. *There's
> > no constructor! *Just populate the items directly. *Each element of
> > the array should, usually, be a myStruct, not a pointer.
> > 2. *You're casting the return from malloc. *Don't do that; it's bad style
> > in C. *(In C++, there are perhaps sound reasons for void * not to
> > automatically convert; in C, there aren't, so it converts automatically..
> > Casting pointer conversions like this just hides bugs.)

>
> They do that though, don't they?


why do you keep saying that?
is it funny?
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      10-31-2010
On 31 Oct, 12:46, Richard <rgrd...@gmail.com> wrote:
> Nick Keighley <nick_keighley_nos...@hotmail.com> writes:
> > On 30 Oct, 22:01, "Scouser" <sco...@scouse-no-spam.com> wrote:
> >> "Seebs" <usenet-nos...@seebs.net> wrote in message

>
> >>news:slrnibeidt.fc7.usenet-...

>
> >> > This can't be correct. *Not seeing the declaration of myStructArray, I
> >> > can't be sure what's wrong with it, but it should be either:
> >> > myStruct *myStructArray;
> >> > myStruct init_values = { 0, 3, 21 }; /* or whatever */
> >> > myStructArray = malloc(1024 * sizeof(MyStruct));
> >> > for (int i = 0; i < 1024; ++i) {
> >> > myStructArray[i] = init_values;
> >> > }
> >> > or
> >> > myStruct **myStructArray;
> >> > myStruct init_values = { 0, 3, 21 }; /* or whatever */
> >> > myStructArray = malloc(1024 * sizeof(MyStruct *));
> >> > for (int i = 0; i < 1024; ++i) {
> >> > myStructArray[i] = malloc(sizeof(MyStruct));
> >> > *myStructArray[i] = init_values;
> >> > }

>
> >> > Usually, in C, you'd do the first. *You're thinking like a C++ programmer,
> >> > and that's led you to two mistakes:

>
> >> > 1. *You're trying to allocate all the items separately, because you're
> >> > thinking of allocation/new as where the constructor happens. *There's
> >> > no constructor! *Just populate the items directly. *Each element of
> >> > the array should, usually, be a myStruct, not a pointer.
> >> > 2. *You're casting the return from malloc. *Don't do that; it's bad style
> >> > in C. *(In C++, there are perhaps sound reasons for void * not to
> >> > automatically convert; in C, there aren't, so it converts automatically.
> >> > Casting pointer conversions like this just hides bugs.)

>
> >> They do that though, don't they?

>
> > why do you keep saying that?
> > is it funny?

>
> Strange. I had always thought you were British. I guess not.


I am. Obviously something passed me by. I'm beginning to think
"Scouser" is a short BASIC program.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Warning:Xst:382 - Register A is equivalent to B mag VHDL 1 05-19-2005 05:10 PM
instancename of current entity/architecture -- equivalent to C++ this??? Eric Peers VHDL 2 11-18-2004 05:23 PM
VHDL equivalent of verilog trireg Sanjeev VHDL 4 07-23-2004 09:55 AM
equivalent types in different packages Lolo VHDL 3 09-22-2003 03:23 PM
Re: Image Scanning - TWAIN equivalent Brendan Duffy ASP .Net 0 07-24-2003 08:29 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57