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.9

;
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:
(remove the x to send email)
http://www.geocities.com/abowers822/