Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > NEWBIE: malloc an array????

Reply
Thread Tools

NEWBIE: malloc an array????

 
 
mike79
Guest
Posts: n/a
 
      11-05-2003
Hi all!

I am having problems properly malloc'ing an array. The problem is, I
have a structure called "array" which contains 2 elements, "int
arraySize" (how many elements are in the array) and "wordArray" (the
actual array itself).

The "word structure" consists of 2 elements, "int occurrence" (the
number of times that particular word occurs in say a sentence, and
"char *string" (the actual word itself).

So the two structures look like this:

typedef struct words
{
int occurrence;
char *string;
}word;

typedef struct arrays
{
int arraySize;
word *wordArray;
}array;

So what I am trying to do is create 1 structure of "array" to keep
track of the number of elements(words) contained in that array, and
the array itself.

The "array" structure contains an array of "word" structures. And the
"word" structure contains an array of "chars" i.e. a string.

So just say I wish to allocate memory for an array of 20 "word"
elements, each word element has a string of 30 chars. How would I do
this?

I tried the code below but i keep getting errors.. please help me!

array *array1;
int element, number;

array1 = malloc(1); // Allocating memory to the array

number = 20; // 20 word elements in the array
array1->wordArray = malloc(number * sizeof *array->wordArray);

element = 0;
while (element < number)
{
array1->wordArray[element].string = malloc(30);
element++;
}

Thank you all so much for your help!
mike79
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      11-05-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (mike79) writes:

> typedef struct words
> {
> int occurrence;
> char *string;
> }word;
>
> typedef struct arrays
> {
> int arraySize;
> word *wordArray;
> }array;
>

[...]
> array *array1;
> int element, number;
>
> array1 = malloc(1); // Allocating memory to the array


An `array' is bigger than 1 byte. You must allocate enough
space.
array1 = malloc (sizeof *array1);

Don't forget to check for a null pointer return from malloc().

> number = 20; // 20 word elements in the array
> array1->wordArray = malloc(number * sizeof *array->wordArray);

^^^^^ array1

You forgot to initialize array1->arraySize.

> element = 0;
> while (element < number)
> {
> array1->wordArray[element].string = malloc(30);


Don't forget to check for a null pointer return.

> element++;
> }


Looks okay, but why not use a `for' loop? And why pre-allocate
30 bytes for each word instead of just allocating however many
are needed when they are needed?

You forgot to initialize array1->wordArray[element].occurrence.
--
"I'm not here to convince idiots not to be stupid.
They won't listen anyway."
--Dann Corbit
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      11-05-2003
On 4 Nov 2003 16:37:46 -0800, (E-Mail Removed) (mike79) wrote:

>Hi all!
>
>I am having problems properly malloc'ing an array. The problem is, I
>have a structure called "array" which contains 2 elements, "int
>arraySize" (how many elements are in the array) and "wordArray" (the
>actual array itself).
>
>The "word structure" consists of 2 elements, "int occurrence" (the
>number of times that particular word occurs in say a sentence, and
>"char *string" (the actual word itself).
>
>So the two structures look like this:
>
>typedef struct words
>{
> int occurrence;
> char *string;
>}word;
>
>typedef struct arrays
>{
> int arraySize;
> word *wordArray;
>}array;
>
>So what I am trying to do is create 1 structure of "array" to keep
>track of the number of elements(words) contained in that array, and
>the array itself.
>
>The "array" structure contains an array of "word" structures. And the


The "array" structure contains a pointer to a "word" structure. This
word structure can be the first of a sequence of such structures which
can be treated as an array.

>"word" structure contains an array of "chars" i.e. a string.


The "word" structure contains a pointer to a char. This char can be
the first of a sequence of such char which can be treated as a string
(if the sequence is properly terminated).

>
>So just say I wish to allocate memory for an array of 20 "word"
>elements, each word element has a string of 30 chars. How would I do
>this?
>
>I tried the code below but i keep getting errors.. please help me!
>
> array *array1;
> int element, number;
>
> array1 = malloc(1); // Allocating memory to the array


You have allocated space for one byte. This is inadequate to hold an
object of type array. To allocate enough space for one "array"
structure, try
array1 = malloc(sizeof *array1);

The real question is: since you only want one "array" structure, why
do you go through all the work of defining a pointer and allocating
space when it is much easier to simply define one instance of the
object
array array1;
and then use the . operator instead of the -> operator.

>
> number = 20; // 20 word elements in the array
> array1->wordArray = malloc(number * sizeof *array->wordArray);


I assume this is a typo and you meant
(number * sizeof *array1->wordArray)

>
> element = 0;
> while (element < number)


Think of a for loop which will do all the initializing, testing, and
incrementing for you
for (element = 0; element < number; element++)

> {
> array1->wordArray[element].string = malloc(30);
> element++;
> }


You should of course be testing every malloc call for success.


<<Remove the del for email>>
 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      11-05-2003
mike79 wrote:
> Hi all!


Hi one !-)

<standard-disclaimer>
Everything I say here is to take with caution, since I don't use C so
frequently. Gurus please correct me if I say some stupidities.
</standard-disclaimer>

> I am having problems properly malloc'ing an array. The problem is, I
> have a structure called "array" which contains 2 elements, "int
> arraySize" (how many elements are in the array) and "wordArray" (the
> actual array itself).
>
> The "word structure" consists of 2 elements, "int occurrence" (the
> number of times that particular word occurs in say a sentence,


Unless you have a need for this to be negative, you'd better make
'occurrences' a size_t IMHO.

> and
> "char *string" (the actual word itself).
>
> So the two structures look like this:
>
> typedef struct words
> {
> int occurrence;
> char *string;
> }word;
>
> typedef struct arrays
> {
> int arraySize;


idem, this would probably be better as a size_t.

> word *wordArray;
> }array;
>
> So what I am trying to do is create 1 structure of "array" to keep
> track of the number of elements(words) contained in that array, and
> the array itself.
>
> The "array" structure contains an array of "word" structures. And the
> "word" structure contains an array of "chars" i.e. a string.
>
> So just say I wish to allocate memory for an array of 20 "word"
> elements, each word element has a string of 30 chars. How would I do
> this?


Why do you want to pre-allocate anything ? You're using dynamic memory,
so why not just create or modify elements when needed ?

> I tried the code below but i keep getting errors.. please help me!
>
> array *array1;
> /*int element, number;*/

size_t element;

You don't need 'number', since you have the wordArray.arraySize

> array1 = malloc(1); // Allocating memory to the array


As Ben Pfaff already pointed, you'll need more than byte !-)
You also want to check the return of malloc(), since it may fail.
array1 = malloc(sizeof *array1);
if (array1 == NULL)
{
/* handle the case, probably exit */
}

> /* number = 20; // 20 word elements in the array */

array1->arraySize = 20;

> array1->wordArray = malloc(number * sizeof *array->wordArray);

I'm not sure you are dereferencing the right thing (any guru around ?)
so to be sure :

array1->wordArray = malloc(array1->arraySize
* sizeof *(array1->wordArray)
);

here again, you want to check the return of malloc()
if (array1->wordArray == NULL)
{
/* handle the case, probably exit */
}


> /* element = 0; */
> /*while (element < number)*/

for (element = 0; element < array1->arraySize; element++)
> {
> array1->wordArray[element].string = malloc(30);


here again, you want to check the return of malloc().

> /* element++; the for loop takes care of this */
> }
>
> Thank you all so much for your help!


(this is more about conception and code organization than pure coding
but...)


The (I think) usual way to handle this kind of problem is to write
specialized code for operations on both structs. So this would give you
a word.h // word.c pair and a wordarray.h // wordarray.c pair.

The 'word' module would handle all operations on words, like creation,
destruction, 'occurrences' increase and/or decrease, etc.

The 'wordarray' module would handle all operations on word arrays, like
creation, destruction, adding a word, removing a word, finding a word[1]
etc.

This allow to :
- test, debug etc the word and wordarray modules by themselves
- get rid of word and wordarray internal mechanisms in the main code.
- eventually modify the implementation of word and wordarray without
changing the calling code (wordarray could as well be implemented as a
linked list or whatsoever).
- eventually reuse word and wordarray in other programs.

Then the main code just have to worry about logical operations, not
about implementation.

[1] as an exemple - I guess that your concern here is to count
occurrences of words in a text - you could have (in the wordarray
module) an operation on wordarray that search if a word is already in
the array, increase it's 'occurrences' count if yes, add it to the array
and set it's occurrence count to 1 if not :

/*
* WARNING : Q&D code, just a sketch, not even tested
* could probably be made far better, etc...
*/
int wordarray_countWord(wordArray *the_array, const char *what)
{
size_t i = 0;
int found = 0;
int err = 0;

/*
* look for 'what' in the array,
* increase its occurences count if found
*/
for (i = 0; i < the_array.size; i++)
{
if (strcmp(the_array[i], what) == 0)
{
/*
* we suppose that wordArray stores
* an array of word*, not an array of word
*/
the_array[i]->occurrences += 1;
found = 1;
break;
}
}

/*
* 'what' has not been found, so we had it
* with an occurence count at 1.
* NB : the wordarray_addWord() function takes
* care of creating the 'word' object from the
* string and occurrence count.
*/
if (! found)
{
err = wordarray_addWord(what, 1);
}

return err;
}


So in the main program module, you'd just need this :

int countWords(wordarray *the_array, wordParser *parser)
{
char *what;
int err = 0;

while ( (what = wordparser_getNextWord(parser, 0)) != NULL)
{
err = wordarray_countWord(what);
free(what);
what = NULL;

if (err != 0)
{
/* handle the error */
}
}

return err;
}

My 2 cents...
Bruno

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      11-05-2003
mike79 wrote:
>
> I am having problems properly malloc'ing an array. The problem is,
> I have a structure called "array" which contains 2 elements, "int
> arraySize" (how many elements are in the array) and "wordArray"
> (the actual array itself).
>
> The "word structure" consists of 2 elements, "int occurrence"
> (the number of times that particular word occurs in say a sentence,
> and "char *string" (the actual word itself).
>
> So the two structures look like this:
>
> typedef struct words
> {
> int occurrence;
> char *string;
> }word;
>
> typedef struct arrays
> {
> int arraySize;
> word *wordArray;
> }array;
>
> So what I am trying to do is create 1 structure of "array" to keep
> track of the number of elements(words) contained in that array, and
> the array itself.
>
> The "array" structure contains an array of "word" structures. And the
> "word" structure contains an array of "chars" i.e. a string.


STOP right here. The word structure, as you have defined it,
contains an int, and A POINTER TO a char. It DOES NOT contain an
array of chars.

Similarly, your array contains an int and a POINTER TO a word.

In neither case has the pointer been initialized, and it cannot be
initialized until the storage that holds it has been allocated.
After that memory for it to point to must be allocated, and the
pointer set to point to that space. Also remember that malloc()
can fail, and each call must be checked for success.

Now start over designing your code.

--
Chuck F ((E-Mail Removed)) ((E-Mail Removed))
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
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
to malloc or not to malloc?? Johs32 C Programming 4 03-30-2006 10:03 AM
porting non-malloc code to malloc micromysore@gmail.com C Programming 3 02-19-2005 05:39 AM
Malloc/Free - freeing memory allocated by malloc Peter C Programming 34 10-22-2004 10:23 AM
free'ing malloc'd structure with malloc'd members John C Programming 13 08-02-2004 11:45 AM
Re: free'ing malloc'd structure with malloc'd members ravi C Programming 0 07-30-2004 12:42 PM



Advertisments