Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Allocating memory for struct - when?

Reply
Thread Tools

Allocating memory for struct - when?

 
 
fix
Guest
Posts: n/a
 
      05-02-2004
Hi all,
I am writing a program using some structs, it is not running and I
believe it is because there's some memory leak - the debugger tells me
that the code causes the problem is in the malloc function.
Is there any general rules that tell me when to allocate memory?
I thought I don't have to if it is a variable that's not a pointer, and
I have to if it is.
I am a bit confused about the arrays particularly.
In normal situations, memory is allocated for array[10] and I don't have
to do so, but if I want to use a pointer so that the array can be
dynamic, I shall use *array and allocate the amount of memory I want,
like array = malloc(sizeof(data_type) * number_of_item), right?
And if I am storing a "string" (char array) in a struct, what happens.
I declared it as:

typedef struct {
void *obj;
char key[];
} HashTableEntry;

What I do to initialize the object is:

HashTableEntry *hte = malloc(sizeof(HashTableEntry));
// "key" is a defined char array
strcpy(hte->key, key);
hte->obj = NULL;

How do the program know how much memory have to be allocated for the
HashTableEntry? It seems that it is dynamically sized, it depends on the
char array key.
And one more thing is, I can't reverse the order of the two members, if
I do so, the program does not compile. Is there any link between the
problem I have said above?
Thanks all!

 
Reply With Quote
 
 
 
 
Karthik
Guest
Posts: n/a
 
      05-02-2004
fix wrote:
> Hi all,
> I am writing a program using some structs, it is not running and I
> believe it is because there's some memory leak - the debugger tells me
> that the code causes the problem is in the malloc function.
> Is there any general rules that tell me when to allocate memory?
> I thought I don't have to if it is a variable that's not a pointer, and
> I have to if it is.
> I am a bit confused about the arrays particularly.
> In normal situations, memory is allocated for array[10] and I don't have
> to do so, but if I want to use a pointer so that the array can be
> dynamic, I shall use *array and allocate the amount of memory I want,
> like array = malloc(sizeof(data_type) * number_of_item), right?
> And if I am storing a "string" (char array) in a struct, what happens.
> I declared it as:
>
> typedef struct {
> void *obj;
> char key[];

Whatz this ???

> } HashTableEntry;
>
> What I do to initialize the object is:
>
> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
> // "key" is a defined char array
> strcpy(hte->key, key);


This is directly related to the problem 1 mentioned before. You are
not allocating memory for the field - 'key' . Try this :


typedef struct {
void *obj;
char * key;
} HashTableEntry;

HashTableEntry *hte = malloc(sizeof(HashTableEntry));
// "key" is a defined char array
key = malloc(sizeof(char) * MAX_CHAR_LEN);
strcpy(hte->key, key);
hte->obj = NULL;


This should help ..
Dont forget to delete the pointers when deleting the object.


free(hte) ; // Memory leak


free(obj);
free(key);
free(hte);
// Pretty cool . But you still need to make sure that indeed the
fields were allocated to be freed...

HTH
--
Karthik
Humans please 'removeme_' for my real email.
 
Reply With Quote
 
 
 
 
Karthik
Guest
Posts: n/a
 
      05-02-2004
Karthik wrote:

> fix wrote:
>
>> Hi all,
>> I am writing a program using some structs, it is not running and I
>> believe it is because there's some memory leak - the debugger tells me
>> that the code causes the problem is in the malloc function.
>> Is there any general rules that tell me when to allocate memory?
>> I thought I don't have to if it is a variable that's not a pointer,
>> and I have to if it is.
>> I am a bit confused about the arrays particularly.
>> In normal situations, memory is allocated for array[10] and I don't
>> have to do so, but if I want to use a pointer so that the array can be
>> dynamic, I shall use *array and allocate the amount of memory I want,
>> like array = malloc(sizeof(data_type) * number_of_item), right?
>> And if I am storing a "string" (char array) in a struct, what happens.
>> I declared it as:
>>
>> typedef struct {
>> void *obj;
>> char key[];

>
> Whatz this ???
>
>> } HashTableEntry;
>>
>> What I do to initialize the object is:
>>
>> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
>> // "key" is a defined char array
>> strcpy(hte->key, key);

>
>
> This is directly related to the problem 1 mentioned before. You are
> not allocating memory for the field - 'key' . Try this :
>
>
> typedef struct {
> void *obj;
> char * key;
> } HashTableEntry;
>
> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
> // "key" is a defined char array
> key = malloc(sizeof(char) * MAX_CHAR_LEN);

Instead - better -
key = malloc(sizeof(char) * (strlen(key) + 1 ));
// Remember the '\0' char

> strcpy(hte->key, key);
> hte->obj = NULL;
>
>
> This should help ..
> Dont forget to delete the pointers when deleting the object.
>
>
> free(hte) ; // Memory leak
>
>
> free(obj);
> free(key);
> free(hte);
> // Pretty cool . But you still need to make sure that indeed the
> fields were allocated to be freed...
>
> HTH



--
Karthik
Humans please 'removeme_' for my real email.
 
Reply With Quote
 
Régis Troadec
Guest
Posts: n/a
 
      05-02-2004

"fix" <(E-Mail Removed)> a écrit dans le message de
news:c73jer$2ft$(E-Mail Removed)...
> Hi all,


Hi,

[snipped]

> typedef struct {
> void *obj;
> char key[];


key is for the moment an array whose the number of elements is unknown, it's
an incomplete type (say, flexible array). A thing you can do here is to
precise the number of elements you want, char key[50]; for example ( a
#define directive may also help), or use a pointer.

> } HashTableEntry;
>
> What I do to initialize the object is:
> HashTableEntry *hte = malloc(sizeof(HashTableEntry));


/* hte tot test */
if (hte != NULL)
{

> // "key" is a defined char array
> strcpy(hte->key, key);


Assuming hte->key has now a complete type with a well-known size like said
above, using strncpy() instead of strcpy() will prevent of writing outside
the bounds of the hte->key array:

/* 50-1 to write at least one null terminating character in hte->key, only
49 characters
from key are copied into hte->key */
strncpy(hte->key, key, 50-1);

> hte->obj = NULL;
>
> How do the program know how much memory have to be allocated for the
> HashTableEntry? It seems that it is dynamically sized, it depends on the
> char array key.


Your structure HashTableEntry contains a pointer to a void element and,
still assuming the member key in the structure is now sized to 50, 50 char
contiguous elements. The compiler knows the space it needs to store such
things (IOW, he knows how many bytes are necessary to store an adress of a
void element and 50 characters. Furthermore, the compiler adds padding bits
between the members of your structure (not before the first member, here
obj) to correctly align the data in memory.

> And one more thing is, I can't reverse the order of the two members, if
> I do so, the program does not compile. Is there any link between the
> problem I have said above?


Yes, since the key member was an incomplete type (remember, flexible array)
and placed first in the structure, the compiler was unable to determine the
size of key and where he would have stored obj. If key is placed in the last
position, it makes sense : I don't know the real policy used by the
compiler, but it can view key as a pointer to a char.


Regis


 
Reply With Quote
 
Régis Troadec
Guest
Posts: n/a
 
      05-02-2004

"fix" <(E-Mail Removed)> a écrit dans le message de
news:c73jer$2ft$(E-Mail Removed)...
> Hi all,


Hi again,

I forgot to answer to other points.

> I am writing a program using some structs, it is not running and I
> believe it is because there's some memory leak - the debugger tells me
> that the code causes the problem is in the malloc function.
> Is there any general rules that tell me when to allocate memory?


The general policy is to allocate memory for your pointers as soon as you
need to use them and desallocate them as soon as you don't need them anymore
in your program. IMHO, by using pointers, allocating all the needed memory
at the beginning of a program to desallocate it at the end is nonsense.

> I thought I don't have to if it is a variable that's not a pointer, and
> I have to if it is.
> I am a bit confused about the arrays particularly.
> In normal situations, memory is allocated for array[10] and I don't have
> to do so, but if I want to use a pointer so that the array can be
> dynamic, I shall use *array and allocate the amount of memory I want,


....or array : array->something against (*array).something, which one is
easier to read?

> like array = malloc(sizeof(data_type) * number_of_item), right?


Right.

Regis


 
Reply With Quote
 
fix
Guest
Posts: n/a
 
      05-02-2004


Karthik wrote:

> Karthik wrote:
>
>> fix wrote:
>>
>>> Hi all,
>>> I am writing a program using some structs, it is not running and I
>>> believe it is because there's some memory leak - the debugger tells
>>> me that the code causes the problem is in the malloc function.
>>> Is there any general rules that tell me when to allocate memory?
>>> I thought I don't have to if it is a variable that's not a pointer,
>>> and I have to if it is.
>>> I am a bit confused about the arrays particularly.
>>> In normal situations, memory is allocated for array[10] and I don't
>>> have to do so, but if I want to use a pointer so that the array can
>>> be dynamic, I shall use *array and allocate the amount of memory I
>>> want, like array = malloc(sizeof(data_type) * number_of_item), right?
>>> And if I am storing a "string" (char array) in a struct, what happens.
>>> I declared it as:
>>>
>>> typedef struct {
>>> void *obj;
>>> char key[];

>>
>>
>> Whatz this ???


Just like the function header some_fct(int some_int, char char_array[]),
I can't do that?

>>> } HashTableEntry;
>>>
>>> What I do to initialize the object is:
>>>
>>> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
>>> // "key" is a defined char array
>>> strcpy(hte->key, key);

>>
>>
>>
>> This is directly related to the problem 1 mentioned before. You
>> are not allocating memory for the field - 'key' . Try this :
>>
>>
>> typedef struct {
>> void *obj;
>> char * key;
>> } HashTableEntry;
>>
>> HashTableEntry *hte = malloc(sizeof(HashTableEntry));
>> // "key" is a defined char array
>> key = malloc(sizeof(char) * MAX_CHAR_LEN);

>
> Instead - better -
> key = malloc(sizeof(char) * (strlen(key) + 1 ));
> // Remember the '\0' char


Actually I want to store the string in the struct, not pointing to
somewhere out there, is that possible?

>> strcpy(hte->key, key);
>> hte->obj = NULL;
>>
>>
>> This should help ..
>> Dont forget to delete the pointers when deleting the object.
>>
>>
>> free(hte) ; // Memory leak
>>
>>
>> free(obj);
>> free(key);
>> free(hte);
>> // Pretty cool . But you still need to make sure that indeed the
>> fields were allocated to be freed...
>>
>> HTH

>
>
>


 
Reply With Quote
 
fix
Guest
Posts: n/a
 
      05-02-2004


Régis Troadec wrote:

> "fix" <(E-Mail Removed)> a écrit dans le message de
> news:c73jer$2ft$(E-Mail Removed)...
>
>>Hi all,

>
>
> Hi again,
>
> I forgot to answer to other points.
>
>
>>I am writing a program using some structs, it is not running and I
>>believe it is because there's some memory leak - the debugger tells me
>>that the code causes the problem is in the malloc function.
>>Is there any general rules that tell me when to allocate memory?

>
>
> The general policy is to allocate memory for your pointers as soon as you
> need to use them and desallocate them as soon as you don't need them anymore
> in your program. IMHO, by using pointers, allocating all the needed memory
> at the beginning of a program to desallocate it at the end is nonsense.
>
>
>>I thought I don't have to if it is a variable that's not a pointer, and
>>I have to if it is.
>>I am a bit confused about the arrays particularly.
>>In normal situations, memory is allocated for array[10] and I don't have
>>to do so, but if I want to use a pointer so that the array can be
>>dynamic, I shall use *array and allocate the amount of memory I want,

>
>
> ...or array : array->something against (*array).something, which one is
> easier to read?


How could I use it like an array?
I can do array[0], .... array[5] if I declared int array[10],
and *array to access the data and array++ to go to the next one.

>>like array = malloc(sizeof(data_type) * number_of_item), right?

>
>
> Right.
>
> Regis
>
>


 
Reply With Quote
 
fix
Guest
Posts: n/a
 
      05-02-2004


Régis Troadec wrote:

> "fix" <(E-Mail Removed)> a écrit dans le message de
> news:c73jer$2ft$(E-Mail Removed)...
>
>>Hi all,

>
>
> Hi,
>
> [snipped]
>
>
>>typedef struct {
>>void *obj;
>>char key[];

>
>
> key is for the moment an array whose the number of elements is unknown, it's
> an incomplete type (say, flexible array). A thing you can do here is to
> precise the number of elements you want, char key[50]; for example ( a
> #define directive may also help), or use a pointer.


But I don't know how long the char array will be and I want to store it
in the struct.

>>} HashTableEntry;
>>
>>What I do to initialize the object is:
>>HashTableEntry *hte = malloc(sizeof(HashTableEntry));

>
>
> /* hte tot test */
> if (hte != NULL)
> {
>
>
>>// "key" is a defined char array
>>strcpy(hte->key, key);

>
>
> Assuming hte->key has now a complete type with a well-known size like said
> above, using strncpy() instead of strcpy() will prevent of writing outside
> the bounds of the hte->key array:
>
> /* 50-1 to write at least one null terminating character in hte->key, only
> 49 characters
> from key are copied into hte->key */
> strncpy(hte->key, key, 50-1);
>
>
>>hte->obj = NULL;
>>
>>How do the program know how much memory have to be allocated for the
>>HashTableEntry? It seems that it is dynamically sized, it depends on the
>>char array key.

>
>
> Your structure HashTableEntry contains a pointer to a void element and,
> still assuming the member key in the structure is now sized to 50, 50 char
> contiguous elements. The compiler knows the space it needs to store such
> things (IOW, he knows how many bytes are necessary to store an adress of a
> void element and 50 characters. Furthermore, the compiler adds padding bits
> between the members of your structure (not before the first member, here
> obj) to correctly align the data in memory.
>
>
>>And one more thing is, I can't reverse the order of the two members, if
>>I do so, the program does not compile. Is there any link between the
>>problem I have said above?

>
>
> Yes, since the key member was an incomplete type (remember, flexible array)
> and placed first in the structure, the compiler was unable to determine the
> size of key and where he would have stored obj. If key is placed in the last
> position, it makes sense : I don't know the real policy used by the
> compiler, but it can view key as a pointer to a char.
>
>
> Regis
>
>


 
Reply With Quote
 
Regis Troadec
Guest
Posts: n/a
 
      05-02-2004

"fix" <(E-Mail Removed)> a ecrit dans le message de
news:c73s1d$90e$(E-Mail Removed)...
> >
> > key is for the moment an array whose the number of elements is unknown,

it's
> > an incomplete type (say, flexible array). A thing you can do here is to
> > precise the number of elements you want, char key[50]; for example ( a
> > #define directive may also help), or use a pointer.

>
> But I don't know how long the char array will be and I want to store it
> in the struct.
>


Don't you know at least the maximum size?

Regis


 
Reply With Quote
 
Regis Troadec
Guest
Posts: n/a
 
      05-02-2004

"fix" <(E-Mail Removed)> a ecrit dans le message de
news:c73rv2$90e$(E-Mail Removed)...
> >
> >>I thought I don't have to if it is a variable that's not a pointer, and
> >>I have to if it is.
> >>I am a bit confused about the arrays particularly.
> >>In normal situations, memory is allocated for array[10] and I don't have
> >>to do so, but if I want to use a pointer so that the array can be
> >>dynamic, I shall use *array and allocate the amount of memory I want,

> >
> >
> > ...or array : array->something against (*array).something, which one is
> > easier to read?

>
> How could I use it like an array?
> I can do array[0], .... array[5] if I declared int array[10],
> and *array to access the data and array++ to go to the next one.


It was a general comment about pointers. If array is a pointer in your case,
you can still use the subscript notation array[i-th] to access the elements
when it's allocated.

Regis


 
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
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
allocating an unsigned int memory buffer for C (swig) struct njuk.njuk@gmail.com Python 0 12-05-2008 02:54 AM
Allocating vector of strings seem to crash. Allocating array ofstrings seems to be ok . Rakesh Kumar C++ 5 12-21-2007 10:42 AM
error when allocating memory using a pointer inside a struct via a function elmafiacs@yahoo.es C Programming 7 02-23-2005 04:02 AM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments