473,467 Members | 1,982 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

structs and dynamic memory allocation

hello,
I do have a question regarding structs. I have a struct (profil) which
has a pointer to another struct (point). The struct profil stores the
coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members (the
points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.

Below is a stripped down version of the program, just to get an idea what
I'm trying to do. I'm aware that this is not a pure ANSI C definition
question, but I couldn't find any help to this special problem neither in
K&R nor in the FAQ. So I apreciate every hint.

Best Regards
Roman

#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;

n=2; /* only to allocate memory for this example */

if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct point)))==NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}

/* put some information into the struct */

p1->pt->x=1265.75;
p1->pt->y=150.73;

p1->pt++; /* ugly, I know. Is there a better way to do this? */

p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;

/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt->x);
printf("\nStrukt 1: %f\n", p1->pt->y);

p1->pt++;

printf("\nStrukt 2: %f\n", p1->pt->x);
printf("\nStrukt 2: %f\n", p1->pt->y);

return 0;
}
Nov 13 '05 #1
11 3352
Roman Hartmann wrote:
I would like to know if there is a better way to access struct members
(the points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.
[. . .]
/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;
[. . .]
/* put some information into the struct */

p1->pt->x=1265.75;
p1->pt->y=150.73;

p1->pt++; /* ugly, I know. Is there a better way to do this? */
Yes, how about this:

struct point *pt = p1->pt;
pt[0].x = 1265.75;
pt[0].y = 150.73;
p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;
pt[1].x = 550.55;
pt[1].y = 350.33;

/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt->x);
printf("\nStrukt 1: %f\n", p1->pt->y);

p1->pt++;

printf("\nStrukt 2: %f\n", p1->pt->x);
printf("\nStrukt 2: %f\n", p1->pt->y);

return 0;
}


int i;
for (i = 0; i < n; ++i)
{
printf("\nStrukt %d: %f\n", i + 1, pt[i].x);
printf("\nStrukt %d: %f\n", i + 1, pt[i].y);
}

Regards,

Russell Hanneken
rg********@pobox.com
Remove the 'g' from my address to send me mail.
Nov 13 '05 #2
Russell Hanneken wrote:
Roman Hartmann wrote:

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;
[ . . . ]
struct point *pt = p1->pt;
pt[0].x = 1265.75;
pt[0].y = 150.73;

pt[1].x = 550.55;
pt[1].y = 350.33;

int i;


Oops; both i and pt need to be declared at the beginning of main. Unless
you're writing code to conform to the new (1999) C standard (which you
probably aren't), local variable declarations have to be at the beginning of
a block, before any non-declaration code.

Regards,

Russell Hanneken
rg********@pobox.com
Remove the 'g' from my address to send me mail.
Nov 13 '05 #3

"Russell Hanneken" <rg********@pobox.com> schrieb im Newsbeitrag
news:a4*****************@newsread4.news.pas.earthl ink.net...
Roman Hartmann wrote:
I would like to know if there is a better way to access struct members
(the points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.

[. . .]

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;

[. . .]

/* put some information into the struct */

p1->pt->x=1265.75;
p1->pt->y=150.73;

p1->pt++; /* ugly, I know. Is there a better way to do this? */


Yes, how about this:

struct point *pt = p1->pt;
pt[0].x = 1265.75;
pt[0].y = 150.73;


Yes!
It's much easier to deal with the points now that way.
p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;


pt[1].x = 550.55;
pt[1].y = 350.33;



/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt->x);
printf("\nStrukt 1: %f\n", p1->pt->y);

p1->pt++;

printf("\nStrukt 2: %f\n", p1->pt->x);
printf("\nStrukt 2: %f\n", p1->pt->y);

return 0;
}


int i;
for (i = 0; i < n; ++i)
{
printf("\nStrukt %d: %f\n", i + 1, pt[i].x);
printf("\nStrukt %d: %f\n", i + 1, pt[i].y);
}

Regards,
Russell Hanneken


thanks a lot!
Roman
Nov 13 '05 #4
On Tue, 04 Nov 2003 16:37:40 +0100, Roman Hartmann wrote:
#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;

n=2; /* only to allocate memory for this example */

if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)
This line can be written more simply:

if ((p1 = malloc(sizeof *p1)) == NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct point)))==NULL)
This line too:

if ((p1->pt = malloc(n * sizeof *p1->pt)) == NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}

/* put some information into the struct */

p1->pt->x=1265.75;
p1->pt->y=150.73;

p1->pt++; /* ugly, I know. Is there a better way to do this? */

p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;


The only problem I see here is the unnecessary incrementing and
decrementing of p1->pt. There is nothing wrong (or unsafe) with
using an expression like p1->pt->x, but to avoid incrementing and
decrementing p1->pt I would do the above like this:

p1->pt[0].x = 1265.75;
p1->pt[0].y = 150.73;
p1->pt[1].x = 550.55;
p1->pt[1].y = 350.33;

-Sheldon

Nov 13 '05 #5
On Tue, 4 Nov 2003 16:37:40 +0100
"Roman Hartmann" <rh*******@bluewin.ch> wrote:
hello,
I do have a question regarding structs. I have a struct (profil)
which has a pointer to another struct (point). The struct profil
stores the coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members
(the points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.
Yes, there are ways which IMHO are better and safer. If a is a pointer,
a[0] is the object a points to, a[1] is the next object (if there is
one) etc. I.e. although pointers and arrays are differed, you can use
a pointer as if it was an array in THIS instance.
Below is a stripped down version of the program, just to get an idea
what I'm trying to do. I'm aware that this is not a pure ANSI C
definition question,
It is a question about how to do something in ANSI C (or any ISO C or
K&R C) so you have come to the right place.
but I couldn't find any help to this special
problem neither in K&R nor in the FAQ. So I apreciate every hint.
It's there somewhere, but you've failed to find it so I'll tell you. We
don't mind people failing to find what they are looking for, or failing
to understand it, it's when people don't try it's a problem.
#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;
You don't use begin (apart from assigning to it) so delete it.
n=2; /* only to allocate memory for this example */

if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)
if((p1=malloc(sizeof *p1))==NULL)
is far safer.

If you had failed to include stdlib.h casting the return value of malloc
prevents the compiler from giving you a warning it is otherwise REQUIRED
to give. It may *still* give a warning, depending on how good the
compiler is. However, why replace a requirement with a hope?

Using sizeof *p1 meens that if you change the type of p1 the malloc will
still allocate the correct amount of space.
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct
point)))==NULL){
if((p1->pt=malloc(n*sizeof *p1->pt))==NULL)

See above.
printf("\nMemory allocation failed\n");
return 1;
}


<snip>

I've replaced the rest of your code with the following...

/* put some information into the struct */

p1->pt[0].x=1265.75;
p1->pt[0].y=150.73;

p1->pt[1].x=550.55;
p1->pt[1].y=350.33;

/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt[0].x);
printf("\nStrukt 1: %f\n", p1->pt[0].y);

printf("\nStrukt 2: %f\n", p1->pt[1].x);
printf("\nStrukt 2: %f\n", p1->pt[1].y);

free(p1->pt);
free(p1);

return 0;
}

Note that I've also freed the storage at the end. After all, we don't
want any memory leaks when you put this in a function ;-)
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.
Nov 13 '05 #6


Roman Hartmann wrote:
hello,
I do have a question regarding structs. I have a struct (profil) which
has a pointer to another struct (point). The struct profil stores the
coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members (the
points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.

Below is a stripped down version of the program, just to get an idea what
I'm trying to do. I'm aware that this is not a pure ANSI C definition
question, but I couldn't find any help to this special problem neither in
K&R nor in the FAQ. So I apreciate every hint.

Best Regards
Roman

#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};


I would add another member to struct profil to keep a count
on the number of points you allocated.

To facilitate the code writing, you can write functions that will
manipulate the data structure.

#include <stdlib.h>
#include <stdio.h>

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
size_t pt_count;
struct profil *previous;
struct profil *next;
};

struct profil *CreateProfil(size_t pt_number);
void AssignPoints(struct point *p, double x, double y);
void PrintProfilPoints(struct profil *p);
void InsertLink(struct profil **root, struct profil *src);
void PrintLinkPoints(struct profil *root);
void FreeLink(struct profil **root);
int main(void)
{
struct profil *link = NULL;
struct profil *p1 = CreateProfil(3);
if(p1 != NULL)
{
AssignPoints(&p1->pt[0],2.33,4.44);
AssignPoints(&p1->pt[1], 4.67, 6.89);
AssignPoints(&p1->pt[2], 7.77,8.98);
InsertLink(&link,p1);
}
if((p1 = CreateProfil(2)) != NULL)
{
AssignPoints(&p1->pt[0], 1.11,2.22);
AssignPoints(&p1->pt[1], 3.33,4.44);
InsertLink(&link,p1);
}
PrintLinkPoints(link);
FreeLink(&link);
return 0;
}

struct profil *CreateProfil(size_t pt_number)
{
struct profil *p;

if((p = malloc(sizeof *p)) == NULL) return NULL;
p->pt_count = pt_number;
p->previous = p->next = NULL;
if(pt_number > 0)
{
if((p->pt = malloc(pt_number*(sizeof *p->pt))) == NULL)
{
free(p);
return NULL;
}
}
else p->pt = NULL;
return p;
}

void AssignPoints(struct point *p, double x, double y)
{
p->x = x;
p->y = y;
return;
}

void PrintProfilPoints(struct profil *p)
{
size_t i;

for(i = 0; i < p->pt_count; i++)
printf("point: x = %.2f\t\ty = %.2f\n",p->pt[i].x,
p->pt[i].y);
return;
}
void InsertLink(struct profil **root, struct profil *src)
{
if(*root != NULL)
{
src->next = *root;
(*root)->previous = src;
}
*root = src;
return;
}

void PrintLinkPoints(struct profil *root)
{
size_t i = 1;
if(root)
{
for( ; root->next; root = root->next);
for( ; root; root = root->previous)
{
printf("Link: %u\n",i++);
PrintProfilPoints(root);
putchar('\n');
}
}
return;
}

void FreeLink(struct profil **root)
{
struct profil *tmp;

for( ; *root; *root = tmp)
{
tmp = (*root)->next;
free((*root)->pt);
free(*root);
}
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 13 '05 #7
"Roman Hartmann" <rh*******@bluewin.ch> wrote in message news:<3f**********@news.bluewin.ch>...
hello,
I do have a question regarding structs. I have a struct (profil) which
has a pointer to another struct (point). The struct profil stores the
coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members (the
points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.
You could write functions to hide this access:

void setPt (struct pt *p, double x, double y)
{
p->x = x;
p->y = y;
}

void setProfilePt (struct profile *p, size_t idx, double x, double
y)
{
setPt (&(p->pt[idx]), x, y);
}

I'll show their use below.

Below is a stripped down version of the program, just to get an idea what
I'm trying to do. I'm aware that this is not a pure ANSI C definition
question, but I couldn't find any help to this special problem neither in
K&R nor in the FAQ. So I apreciate every hint.

Best Regards
Roman

#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;

n=2; /* only to allocate memory for this example */

if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)
Don't cast the return value of malloc(). You don't need to (as of
C89, anyway), and it may supress a compiler warning if you ever forget
to #include stdlib.h.

This is a bit cleaner, and works just as well:

if ((p1 = malloc (sizeof *p1)) != NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct point)))==NULL)
Same point as above.

if ((p1->pt = malloc (n * sizeof *(p1->pt))) == NULL) {
printf("\nMemory allocation failed\n");
return 1;
}

/* put some information into the struct */

p1->pt->x=1265.75;
p1->pt->y=150.73;

p1->pt++; /* ugly, I know. Is there a better way to do this? */
Use array subscript notation instead:

p1->pt[0].x = 1265.75;
p1->pt[0].y = 150.73;

p1->pt[1].x = 550.55;
p1->pt[1].y = 350.33;

Actually, this is where you'd use the assignment functions I defined
above:

setProfilePt (p, 0, 1265.75, 150.73);
setProfilePt (p, 1, 550.55, 350.33);

p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;

/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt->x);
printf("\nStrukt 1: %f\n", p1->pt->y);

p1->pt++;

printf("\nStrukt 2: %f\n", p1->pt->x);
printf("\nStrukt 2: %f\n", p1->pt->y);
Same thing: use array subscript notation instead of incrementing your
pointer.

printf ("\nStrukt 1: {%f,%f}\n", p1->pt[0].x, p1->pt[0].y);
printf ("\nStrukt 2: {%f,%f}\n", p1->pt[1].x, p1->pt[1].y);

This would also be a good excuse for creating accessor functions:

double ptX (struct pt p) { return p.x; }
double ptY (struct pt p) { return p.y; }

void getProfilePt (struct profile *p, size_t idx, double *x,
double *y)
{
*x = ptX (p->pt[idx]);
*y = ptY (p->pt[idx]);
}
return 0;
}

Nov 13 '05 #8
"Sheldon Simms" <sh**********@yahoo.com> schrieb im Newsbeitrag
news:pa****************************@yahoo.com...
On Tue, 04 Nov 2003 16:37:40 +0100, Roman Hartmann wrote:
[ ...]
if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)


This line can be written more simply:

if ((p1 = malloc(sizeof *p1)) == NULL)


I never dealt with malloc before, so I really appreciate this hint.
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct point)))==NULL)


This line too:

if ((p1->pt = malloc(n * sizeof *p1->pt)) == NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}
[ ... ]
p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;


The only problem I see here is the unnecessary incrementing and
decrementing of p1->pt. There is nothing wrong (or unsafe) with
using an expression like p1->pt->x, but to avoid incrementing and
decrementing p1->pt I would do the above like this:

p1->pt[0].x = 1265.75;
p1->pt[0].y = 150.73;
p1->pt[1].x = 550.55;
p1->pt[1].y = 350.33;


That is simpler and more obvious than incrementing a pointer.

thanks a lot
Roman
-Sheldon

Nov 13 '05 #9

"Mark Gordon" <sp******@flash-gordon.me.uk> schrieb im Newsbeitrag
news:20031104165759.06caa403.sp******@flash-gordon.me.uk...
On Tue, 4 Nov 2003 16:37:40 +0100
"Roman Hartmann" <rh*******@bluewin.ch> wrote:
hello,
I do have a question regarding structs. I have a struct (profil)
which has a pointer to another struct (point). The struct profil
stores the coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members
(the points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.
Yes, there are ways which IMHO are better and safer. If a is a pointer,
a[0] is the object a points to, a[1] is the next object (if there is
one) etc. I.e. although pointers and arrays are differed, you can use
a pointer as if it was an array in THIS instance.


Well, I couldn't see the most obvious solution.
Below is a stripped down version of the program, just to get an idea
what I'm trying to do. I'm aware that this is not a pure ANSI C
definition question,


It is a question about how to do something in ANSI C (or any ISO C or
K&R C) so you have come to the right place.
but I couldn't find any help to this special
problem neither in K&R nor in the FAQ. So I apreciate every hint.


It's there somewhere, but you've failed to find it so I'll tell you. We
don't mind people failing to find what they are looking for, or failing
to understand it, it's when people don't try it's a problem.
#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;


You don't use begin (apart from assigning to it) so delete it.
n=2; /* only to allocate memory for this example */

if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)


if((p1=malloc(sizeof *p1))==NULL)
is far safer.


Thanks for this info.
If you had failed to include stdlib.h casting the return value of malloc
prevents the compiler from giving you a warning it is otherwise REQUIRED
to give. It may *still* give a warning, depending on how good the
compiler is. However, why replace a requirement with a hope?

Using sizeof *p1 meens that if you change the type of p1 the malloc will
still allocate the correct amount of space.
Well, pointers and dynamic memory allocation seem to be the hard part for
newbies on C.
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct
point)))==NULL){


if((p1->pt=malloc(n*sizeof *p1->pt))==NULL)

See above.
printf("\nMemory allocation failed\n");
return 1;
}


<snip>

I've replaced the rest of your code with the following...

/* put some information into the struct */

p1->pt[0].x=1265.75;
p1->pt[0].y=150.73;

p1->pt[1].x=550.55;
p1->pt[1].y=350.33;


I don't know why I didn't have figured out, myself. It's so obvious.
/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt[0].x);
printf("\nStrukt 1: %f\n", p1->pt[0].y);

printf("\nStrukt 2: %f\n", p1->pt[1].x);
printf("\nStrukt 2: %f\n", p1->pt[1].y);

free(p1->pt);
free(p1);

return 0;
}

Note that I've also freed the storage at the end. After all, we don't
want any memory leaks when you put this in a function ;-)
Thanks a lot. I appreciate your help.

Roman
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.

Nov 13 '05 #10

"Al Bowers" <xa******@rapidsys.com> schrieb im Newsbeitrag
news:bo*************@ID-169908.news.uni-berlin.de...


Roman Hartmann wrote:
hello,
I do have a question regarding structs. I have a struct (profil) which
has a pointer to another struct (point). The struct profil stores the
coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members (the points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.

Below is a stripped down version of the program, just to get an idea what I'm trying to do. I'm aware that this is not a pure ANSI C definition
question, but I couldn't find any help to this special problem neither in K&R nor in the FAQ. So I apreciate every hint.

Best Regards
Roman

#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};
I would add another member to struct profil to keep a count
on the number of points you allocated.

To facilitate the code writing, you can write functions that will
manipulate the data structure.


Good idea. I will do that if I know better what I'm actually doing;-)
#include <stdlib.h>
#include <stdio.h>

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
size_t pt_count;
struct profil *previous;
struct profil *next;
};

struct profil *CreateProfil(size_t pt_number);
void AssignPoints(struct point *p, double x, double y);
void PrintProfilPoints(struct profil *p);
void InsertLink(struct profil **root, struct profil *src);
void PrintLinkPoints(struct profil *root);
void FreeLink(struct profil **root);
int main(void)
{
struct profil *link = NULL;
struct profil *p1 = CreateProfil(3);
if(p1 != NULL)
{
AssignPoints(&p1->pt[0],2.33,4.44);
AssignPoints(&p1->pt[1], 4.67, 6.89);
AssignPoints(&p1->pt[2], 7.77,8.98);
InsertLink(&link,p1);
}
if((p1 = CreateProfil(2)) != NULL)
{
AssignPoints(&p1->pt[0], 1.11,2.22);
AssignPoints(&p1->pt[1], 3.33,4.44);
InsertLink(&link,p1);
}
PrintLinkPoints(link);
FreeLink(&link);
return 0;
}

struct profil *CreateProfil(size_t pt_number)
{
struct profil *p;

if((p = malloc(sizeof *p)) == NULL) return NULL;
p->pt_count = pt_number;
p->previous = p->next = NULL;
if(pt_number > 0)
{
if((p->pt = malloc(pt_number*(sizeof *p->pt))) == NULL)
{
free(p);
return NULL;
}
}
else p->pt = NULL;
return p;
}

void AssignPoints(struct point *p, double x, double y)
{
p->x = x;
p->y = y;
return;
}

void PrintProfilPoints(struct profil *p)
{
size_t i;

for(i = 0; i < p->pt_count; i++)
printf("point: x = %.2f\t\ty = %.2f\n",p->pt[i].x,
p->pt[i].y);
return;
}
void InsertLink(struct profil **root, struct profil *src)
{
if(*root != NULL)
{
src->next = *root;
(*root)->previous = src;
}
*root = src;
return;
}

void PrintLinkPoints(struct profil *root)
{
size_t i = 1;
if(root)
{
for( ; root->next; root = root->next);
for( ; root; root = root->previous)
{
printf("Link: %u\n",i++);
PrintProfilPoints(root);
putchar('\n');
}
}
return;
}

void FreeLink(struct profil **root)
{
struct profil *tmp;

for( ; *root; *root = tmp)
{
tmp = (*root)->next;
free((*root)->pt);
free(*root);
}
}
Thanks a lot for this. I learned a lot from that example and will probably
use some parts (or at least the concept) of this.
Thanks again!

Roman
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 13 '05 #11

"John Bode" <jo*******@my-deja.com> schrieb im Newsbeitrag
news:43**************************@posting.google.c om...
"Roman Hartmann" <rh*******@bluewin.ch> wrote in message

news:<3f**********@news.bluewin.ch>...
hello,
I do have a question regarding structs. I have a struct (profil) which
has a pointer to another struct (point). The struct profil stores the
coordinates of points.
The problem is that I don't know how many points
there will be in every struct in the end, so I have to allocate memory
dynamically for
them and can't use an array of fixed size, unfortunately.

I would like to know if there is a better way to access struct members (the points).
Accessing struct members with p1->p2->x seems rather ugly and unsafe.


You could write functions to hide this access:
void setPt (struct pt *p, double x, double y)
{
p->x = x;
p->y = y;
}

void setProfilePt (struct profile *p, size_t idx, double x, double
y)
{
setPt (&(p->pt[idx]), x, y);
}

I'll show their use below.

Below is a stripped down version of the program, just to get an idea what I'm trying to do. I'm aware that this is not a pure ANSI C definition
question, but I couldn't find any help to this special problem neither in K&R nor in the FAQ. So I apreciate every hint.

Best Regards
Roman

#include <stdlib.h>
#include <stdio.h>

/* struct with points, used by struct profil */

struct point
{
double x;
double y;
};

struct profil
{
struct point *pt;
struct profil *previous;
struct profil *next;
};

int main(void)
{
int n;

struct profil *p1;
struct profil *begin;

n=2; /* only to allocate memory for this example */

if((p1=(struct profil *) malloc(sizeof(struct profil)))==NULL)


Don't cast the return value of malloc(). You don't need to (as of
C89, anyway), and it may supress a compiler warning if you ever forget
to #include stdlib.h.

This is a bit cleaner, and works just as well:

if ((p1 = malloc (sizeof *p1)) != NULL)


It gives me some confident that all the people are doing the memory
allocation the same way.
{
printf("\nMemory allocation failed\n");
return 1;
}

begin=p1;

if((p1->pt=(struct point *) malloc(n*sizeof(struct point)))==NULL)


Same point as above.

if ((p1->pt = malloc (n * sizeof *(p1->pt))) == NULL)
{
printf("\nMemory allocation failed\n");
return 1;
}

/* put some information into the struct */

p1->pt->x=1265.75;
p1->pt->y=150.73;

p1->pt++; /* ugly, I know. Is there a better way to do this? */


Use array subscript notation instead:

p1->pt[0].x = 1265.75;
p1->pt[0].y = 150.73;

p1->pt[1].x = 550.55;
p1->pt[1].y = 350.33;

Actually, this is where you'd use the assignment functions I defined
above:

setProfilePt (p, 0, 1265.75, 150.73);
setProfilePt (p, 1, 550.55, 350.33);

p1->pt->x=550.55;
p1->pt->y=350.33;

p1->pt--;

/* do something with the structs */
/* instead of printing results, I print the structs out */

printf("\nStrukt 1: %f\n", p1->pt->x);
printf("\nStrukt 1: %f\n", p1->pt->y);

p1->pt++;

printf("\nStrukt 2: %f\n", p1->pt->x);
printf("\nStrukt 2: %f\n", p1->pt->y);


Same thing: use array subscript notation instead of incrementing your
pointer.

printf ("\nStrukt 1: {%f,%f}\n", p1->pt[0].x, p1->pt[0].y);
printf ("\nStrukt 2: {%f,%f}\n", p1->pt[1].x, p1->pt[1].y);

This would also be a good excuse for creating accessor functions:

double ptX (struct pt p) { return p.x; }
double ptY (struct pt p) { return p.y; }

void getProfilePt (struct profile *p, size_t idx, double *x,
double *y)
{
*x = ptX (p->pt[idx]);
*y = ptY (p->pt[idx]);
}

return 0;
}


thanks for your help!
Roman
Nov 13 '05 #12

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

Similar topics

6
by: chris | last post by:
Hi all, I need to know, what is the difference between dynamic memory allocation, and stack allocation ? 1. If I have a class named DestinationAddress, when should I use dynamic memory...
10
by: Patricia Van Hise | last post by:
Is it possible to access a field of a struct which is a field of another struct? Ex. struct subStr{ int num1; int num2; }; struct myStr { int num3; subStr *lock; };
4
by: veera sekhar kota | last post by:
I read structs are stored at stack area or inline-heap based objects. What is meant by inline-heap based objects? I didnt get that. Thanks, Veera.
11
by: toton | last post by:
Hi, I have little confusion about static memory allocation & dynamic allocation for a cluss member. I have class like class Bar{ public: explicit Bar(){ cout<<"bar default"<<endl; }
24
by: Ken | last post by:
In C programming, I want to know in what situations we should use static memory allocation instead of dynamic memory allocation. My understanding is that static memory allocation like using array...
1
by: Peterwkc | last post by:
Hello all expert, i have two program which make me desperate bu after i have noticed the forum, my future is become brightness back. By the way, my problem is like this i the first program was...
3
by: ranjeetasharma81 | last post by:
Hi all, I have a big C-cod, in which there are lots of dynamic memory allocation used. I want to replace dynamic memroy allocation by static arrays. The following are the problems that i am...
14
by: vivek | last post by:
i have some doubts on dynamic memory allocation and stacks and heaps where is the dynamic memory allocation used? in function calls there are some counters like "i" in the below function. Is...
10
by: swornavidhya.mahadevan | last post by:
Which allocation (Static / Dynamic) is suitable for the situation when we are trying to allocate for a overloaded memory when the memory is full and no space to allocate. What will happen if both...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.