Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

need to allocate/free members of a structure individually? 1

Status
Not open for further replies.

svar

Programmer
Aug 12, 2001
349
GR

Ok, this one I saw on a tutorial on the web. It was a linked list

struct node {node *next;
char *something;};
typedef struct node linkedlist;

and in insert and delete it had functions like

void insert(linkedlist *head, char *rec){

..
pointer->something=new_record(*rec)



with new_record using a malloc

Is this nesessary or is somthing like

pointer=(*linkedlist)malloc(sizeof(*linkedlist))
enough?
 
could you plrease be a bit more exlicitly? I mean what is exactly the existing code and what changes would you like to do?

Ion Filipski
1c.bmp
 
Ok, what I do not see is this:
if you look at add_base below, one requests via malloc
a pointer to a new node. Then, to set the string there
one calls function new_record which also calls malloc
I do not see why you need to reserve space individually
for the string, since we have reserved the heap memory for
the node
with
row = (dbase *) malloc (sizeof (dbase));
and this is presumably enough to hold the string

------
struct dbase_rec {
struct dbase_rec *next;
char *record;
};

typedef struct dbase_rec dbase;
Before explaining the linked list's code, I will first explain several of the functions needed to manipulate the records. Since the dbase structure only contains a pointer to a record, each record must be allocated on the heap. When the program is finished with the record, the memory that held it must be released. These operations are performed by the functions new_record and drop_record.

char *
new_record (char *buffer) {
char *rec = (char *) malloc (SZ_RECORD+1);

strcpy (rec, buffer);
return rec;
}

void
drop_record (char *rec) {
free (rec);
}

int
add_dbase (dbase **db, char *rec) {
int cmp;
int status;
dbase *ptr = NULL;
dbase *row = NULL;
dbase *prevptr = NULL;
dbase *nextptr = NULL;

row = (dbase *) malloc (sizeof (dbase));
row->next = NULL;
row->record = new_record (rec);

cmp = 1;
for (ptr = *db; ptr != NULL; ptr = ptr->next) {
cmp = cmp_record (rec, ptr->record);
if (cmp <= 0)
break;

prevptr = ptr;
}

if (cmp != 0) {
nextptr = ptr;
status = 1;

} else {
nextptr = ptr->next;
status = 0;

drop_record (ptr->record);
free (ptr);
}

row->next = nextptr;

if (prevptr != NULL) {
prevptr->next = row;
} else {
*db = row;
}

return status;
}

see the full pages at:
 
> I do not see why you need to reserve space individually
> for the string, since we have reserved the heap memory for
> the node
Yes, and that node contains a pointer to a string, not a string.

This you need a second malloc
Code:
struct dbase_rec {
    struct dbase_rec    *next;
    char                *record;
};

And this one, you don't need a second malloc
Code:
struct dbase_rec {
    struct dbase_rec    *next;
    char                 record[MAX_STRING_LENGTH];
};

Try
Code:
printf( "Size=%d\n", sizeof( struct dbase_rec ) );
for both types of record structure.

The other important thing is that you should NOT be casting malloc in a C program.
> row = (dbase *) malloc (sizeof (dbase));
Should be written as
[tt]row = malloc (sizeof (dbase));[/tt]
Or preferably (since its easier to maintain)
[tt]row = malloc (sizeof *row );[/tt]

If you get a warning like
[tt] implicit declaration of function `malloc'[/tt]
It means that you failed to #include <stdlib.h>
This is a warning which you hide by casting, and it really is one which you should not be ignoring.

If you get a warning like
[tt] invalid conversion from `void*' to `char*'[/tt]
It means that you are using a C++ compiler to compile C code. If you really want to do this in C++, then you should be using new and delete (not malloc and free)

> char *rec = (char *) malloc (SZ_RECORD+1);
What is SZ_RECORD?
Surely the length of the string being copied would be most optimal.
char *rec = malloc(strlen(str)+1);


--
 
Thanks, illustrates well the arrays and pointers are not always equivalent. So let me see if I read this right:
in


row = (dbase *) malloc (sizeof (dbase));
we allocate memory to hold a node(=a char pointer plus a
node pointer)

row->record = new_record (rec);
and here we need to know about the size of the location of the character
string pointer, which one cannot do without knowing the actual
string size

In contrast with a fixed size array we know this size


Am I missing something here?




 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top