472,958 Members | 2,229 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,958 software developers and data experts.

Pointers, structs and memory allocations

Hi, I'm a C-newbie and I would like to know if I am doing something
wrong in the code below. It is working, but I'm afraid it might not be
correct because I don't really understand everything of it. There are
lots of pointers and pointers to pointers which makes me confused.

First my typedef:

typedef struct
{
double re;
double im;
} cplx;

What I need to do first is to allocate memory to hold N pointers to
cplx. I do it with this statement (correct or not?):

cplx **data = (cplx **)malloc(sizeof(cplx *) * N);
if(!data) { /* malloc failed */ ... }

Next I need to malloc space for each struct in the list and fill it
with data. This is what I do (correct or not?):

for(i = 0; i < N; i++)
{
data[i] = (cplx *)malloc(sizeof(cplx));
data[i]->re = i; /* fill with testdata */
data[i]->im = N - i - 1; /* fill with testdata */
}

Then I will call a rearrange-function to rearrange the _pointers_ and
_not_ the data in the array. The function looks like this:

void rearrange(cplx **data, int n_elements)
{
cplx *tmp;
int i;

/* reverse the data */
for(i = 0; i < (n_elements / 2); i++)
{
tmp = data[i];
data[i] = data[n_elements - i - 1];
data[n_elements - i - 1] = tmp;
}
}

I call this function from main() the following way (correct or not?):

rearrange(data, N);

And finally clean up the memory (correct or not?):

for(i = 0; i < N; i++)
free(data[i]);

free(**data);

Finally, is this the right approach if you got a large list of structs
to be rearranged? I guess it's much faster swapping pointers than
swapping the entire data in the structs?
Nov 13 '05 #1
3 2125
On Tue, 11 Nov 2003 05:28:31 -0800, Christian F wrote:
typedef struct
{
double re;
double im;
} cplx;
cplx **data = (cplx **)malloc(sizeof(cplx *) * N); if(!data) { /* malloc
failed */ ... }
Don't cast malloc. It can hide errors, if you've included stdlib.h the
casting is unnesseary.

for(i = 0; i < N; i++)
{
data[i] = (cplx *)malloc(sizeof(cplx));
Again don't cast malloc.
data[i]->re = i; /* fill with testdata */ data[i]->im = N - i - 1; /*
fill with testdata */
}
And finally clean up the memory (correct or not?):

for(i = 0; i < N; i++)
free(data[i]);
Correct.

free(**data);
Not! use:
free(data);

Finally, is this the right approach if you got a large list of structs
to be rearranged? I guess it's much faster swapping pointers than
swapping the entire data in the structs?


Probably yes, if the goal is speed.

Otoh this requires sizeof(cplx*) * N
bytes of extra memory. If N is suficciently large that may be what pushes
your program over the edge to using swap space, resulting in lower overall
speed.
But for most cases the size of the pointerarray would be overshadowed by
the size of the struct so I wouldn't worry about it. But if you vere
reversing an array of ints the pointer array would be a waste.

--
NPV

"the large print giveth, and the small print taketh away"
Tom Waits - Step right up

Nov 13 '05 #2
On Tue, 11 Nov 2003 14:04:06 +0000, Nils Petter Vaskinn wrote:
On Tue, 11 Nov 2003 05:28:31 -0800, Christian F wrote:

Finally, is this the right approach if you got a large list of structs
to be rearranged? I guess it's much faster swapping pointers than
swapping the entire data in the structs?


Probably yes, if the goal is speed.


Just struck me:

For an array of pointers you do N mallocs and 2N copy operations on
pointers.

For an arrray of structs you do 1 malloc (sizeof(cplx)*N) and 2N copy
operations on the struct data.

In this case it all comes down to the speed of your malloc implementation
vs the speed of the copy operations.

Another alternative:

cplx *realData = malloc(sizeof(cplx)*N);
cplx **data = malloc(sizeof(cplx*)*N);

for(int i=0; i<N; ++i) {
data[i] = realData + i;
}

This gives 2 malloc operations and 3N copy operations on pointers.
The way to know which is faster is to profile all three.

--
NPV

"the large print giveth, and the small print taketh away"
Tom Waits - Step right up

Nov 13 '05 #3
Christian F <kh***@telia.com> wrote:
Hi, I'm a C-newbie and I would like to know if I am doing something
wrong in the code below. It is working, but I'm afraid it might not be
correct because I don't really understand everything of it. There are
lots of pointers and pointers to pointers which makes me confused.

First my typedef:

typedef struct
{
double re;
double im;
} cplx;
Though the above is syntactically correct, IMHO it brings you no good.
Hiding structs behind typedefs is only a good idea if the struct needs
to be camouflaged somehow. That is, programs use an abstract type they
do not have to know in depth (like for example the type FILE).

It is arguable that a complex-type should be abstracted to the user, but
on the other hand it should not for the part of the program that works
with the contents of such a struct.

I usually stick to the conservative

struct cplx {...};

..

What I need to do first is to allocate memory to hold N pointers to
cplx. I do it with this statement (correct or not?):

cplx **data = (cplx **)malloc(sizeof(cplx *) * N);
Casting malloc is a no no, especially in this newsgroup. If you have the
appropriate prototype for malloc in place, there is no need to cast its
return value at all. malloc returns a generic pointer, which can be
converted without a cast to any other object pointer type. So if you are
getting diagnostic messages from you compiler, that is rather due to
failure to include tha correct header file (stdlib.h), that to a missing
cast.

Some people argue that in C++ you'ld need cast mallocs return value, but
who would ever want to compile a C program with a C++ compiler? And if
one is programming in C++, why would one use malloc at all? ...

Also I recommend to apply sizeof to an object rather than a type, so
when you change the type of data, there will be no need to change the
malloc call:

struct cplx **data = malloc(sizeof *data * N);

Btw, if N is meant to be constant, I don't see the need to use malloc
at all, but I think this is going to be a parameter of some kind.

if(!data) { /* malloc failed */ ... }

Next I need to malloc space for each struct in the list and fill it
with data. This is what I do (correct or not?):

for(i = 0; i < N; i++)
{
data[i] = (cplx *)malloc(sizeof(cplx));
As explained above:
data[i] = malloc(sizeof *data[i]);
data[i]->re = i; /* fill with testdata */
data[i]->im = N - i - 1; /* fill with testdata */
}

Then I will call a rearrange-function to rearrange the _pointers_ and
_not_ the data in the array. The function looks like this:

void rearrange(cplx **data, int n_elements)
{
cplx *tmp;
int i;

/* reverse the data */
for(i = 0; i < (n_elements / 2); i++)
{
tmp = data[i];
data[i] = data[n_elements - i - 1];
data[n_elements - i - 1] = tmp;
}
}

I call this function from main() the following way (correct or not?):

rearrange(data, N);

And finally clean up the memory (correct or not?):

for(i = 0; i < N; i++)
free(data[i]);
That is ok!

free(**data);
But this one is not. Guess why!

free(data);

Finally, is this the right approach if you got a large list of structs
to be rearranged? I guess it's much faster swapping pointers than
swapping the entire data in the structs?


It depends one the size of the list. It is probably the right approach
for lists that are pretty short (like less than say 1000 elements). At
some point you may recognize that there need to be better ways of doing,
but that is another story... which is better discussed elsewhere.
--
Z (Zo**********@daimlerchrysler.com)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
Nov 13 '05 #4

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

Similar topics

27
by: Susan Baker | last post by:
Hi, I'm just reading about smart pointers.. I have some existing C code that I would like to provide wrapper classes for. Specifically, I would like to provide wrappers for two stucts defined...
3
by: Sameh Halabi | last post by:
Hi I have a strange problem in C , I hope someone may help with it . the problem is as follows : I have an existing big structure (that I can't change) which contains in it groups of...
388
by: maniac | last post by:
Hey guys, I'm new here, just a simple question. I'm learning to Program in C, and I was recommended a book called, "Mastering C Pointers", just asking if any of you have read it, and if it's...
47
by: sunglo | last post by:
Some time a go, in a discussion here in comp.lang.c, I learnt that it's better not to use a (sometype **) where a (void **) is expected (using a cast). Part of the discussion boiled down to the...
5
by: Paminu | last post by:
Why make an array of pointers to structs, when it is possible to just make an array of structs? I have this struct: struct test { int a; int b;
3
by: _TR | last post by:
I love C# and I've been porting a lot of my older C++ code, but there is one app that I haven't quite figured out yet. I suppose I could re-engineer the app from the ground up, but I've already...
17
by: Johan Tibell | last post by:
Could someone outline the pros and cons of typedefing pointers to structs like this? typedef struct exp_ { int val; struct exp_ *child; } *exp; (This is straight from memory so it might not...
19
by: Name and address withheld | last post by:
I am trying to understand how ustr (http://www.and.org/ustr/design) works. Its a string-handling library for C, and it stores strings in the following struct, called a "magic struct" struct Ustr...
2
by: hal | last post by:
Hi, I'm trying to make an array of pointers to 'TwoCounts' structs, where the size of the array is arraySize. Right now I'm just mallocing enough space for all the pointers to the structs, and...
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...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
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...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...

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.