Programming / malloc Q

K

Kamus of Kadizhar

I have a question that's probably not uncommon.

I am reading a number of short strings from a file. Each string gets put
in the next element of an array. I have no idea how many of these strings
there are; I do know they are all short (< 8 bytes). There could be a
handful or as many as a couple of hundred, so we're not talking great
amounts. I don't have any control over how many there will be;
conceivably some dedicated (or misinformed) user could throw in thousands.

What's the best way to allocate memory for this?

Basically, the code is something like this (untested code):

char **keymap;

while( fscanf(fp,"%4095s ",lineBuffer) == 1 ) {
... some validation ...
if( sscanf(lineBuffer,"%7s ",charBuffer) == 1) {
/* we potentially have a keymap */
if( !g_utf8_validate(charBuffer) ) {
/* it's not a valid UTF-8 string */
printf("malformed line >%s< ",charBuffer);
return FALSE;
}
/* now we need to allocate the next element of keymap
* and assign the contents of charBuffer
*/
???????????????????
}
}

I can malloc() each element, but how do I expand the size of keymap?
realloc every time? That seems very wasteful.

--Kamus
 
J

Jens.Toerring

Kamus of Kadizhar said:
I am reading a number of short strings from a file. Each string gets put
in the next element of an array. I have no idea how many of these strings
there are; I do know they are all short (< 8 bytes). There could be a
handful or as many as a couple of hundred, so we're not talking great
amounts. I don't have any control over how many there will be;
conceivably some dedicated (or misinformed) user could throw in thousands.
What's the best way to allocate memory for this?
Basically, the code is something like this (untested code):
char **keymap;
while( fscanf(fp,"%4095s ",lineBuffer) == 1 ) {

Probably fgets() would be better here because it won't stop at spaces
or tabs ((f|s)?scanf() stops at white space or at the maximum field
width, whichever occurs first).
... some validation ...
if( sscanf(lineBuffer,"%7s ",charBuffer) == 1) {

You won't have a space in lineBuffer if you used fscanf()...
/* we potentially have a keymap */
if( !g_utf8_validate(charBuffer) ) {
/* it's not a valid UTF-8 string */
printf("malformed line >%s< ",charBuffer);
return FALSE;
}
/* now we need to allocate the next element of keymap
* and assign the contents of charBuffer
*/
???????????????????
}
}
I can malloc() each element, but how do I expand the size of keymap?
realloc every time? That seems very wasteful.

Start off with a reasonable guess of the number of strings and malloc()
that many char pointers for keymap. If you find that there are more
realloc() for twice as many elements and continue. If this is still not
enough again double the size of keymap etc. When you're done reading the
strings again use realloc() to reduce keymap to as many pointers as you
really needed.
Regards, Jens
 
R

Richard Bos

Kamus of Kadizhar said:
I am reading a number of short strings from a file. Each string gets put
in the next element of an array. I have no idea how many of these strings
there are; I do know they are all short (< 8 bytes). There could be a
handful or as many as a couple of hundred, so we're not talking great
amounts. I don't have any control over how many there will be;
conceivably some dedicated (or misinformed) user could throw in thousands.

What's the best way to allocate memory for this?

Don't allocate each one separately, allocate them in bunches. Create an
extra counter to hold the number of strings you have memory for. When
the number of strings read hits that number, don't allocate one extra,
allocate a whole bunch - say, twenty percent of what you have now. Start
with a reasonable guess; in your case, a hundred or so, perhaps.

Richard
 
C

CBFalconer

Kamus said:
I have a question that's probably not uncommon.

I am reading a number of short strings from a file. Each string
gets put in the next element of an array. I have no idea how
many of these strings there are; I do know they are all short
(< 8 bytes). There could be a handful or as many as a couple of
hundred, so we're not talking great amounts. I don't have any
control over how many there will be; conceivably some dedicated
(or misinformed) user could throw in thousands.

What's the best way to allocate memory for this?

A linked list sounds like the appropriate structure.
 
K

Kamus of Kadizhar

Probably fgets() would be better here because it won't stop at spaces
or tabs ((f|s)?scanf() stops at white space or at the maximum field
width, whichever occurs first).

Thanks for the commentary. I've written tons and tons of code, but not in
the last few years and I'm horribly rusty.... That little tidbit probably
saved me a day of head-scratching.
Start off with a reasonable guess of the number of strings and malloc()
that many char pointers for keymap. If you find that there are more
realloc() for twice as many elements and continue. If this is still not
enough again double the size of keymap etc. When you're done reading the
strings again use realloc() to reduce keymap to as many pointers as you
really needed.

OK, that sounds like a plan.

Thanks,

--Kamus
 
C

CBFalconer

Kamus said:
Thanks for the commentary. I've written tons and tons of code, but not in
the last few years and I'm horribly rusty.... That little tidbit probably
saved me a day of head-scratching.


OK, that sounds like a plan.

Simply download and use ggets.zip from my site. It does all that.

#include "ggets.h"

FILE *fp;
char *buff;
....
while (0 == ggets(&buff)) { /* or fggets(&buff, fp) */
/* do what you wish with buff, which points to a line */
free(buff); /* if you don't need it anymore */
/* else you have copied it somewhere */
}

<http://cbfalconer.home.att.net/download/ggets.zip>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,140
Messages
2,570,810
Members
47,357
Latest member
sitele8746

Latest Threads

Top