Critic of the given code.

R

Richard Heathfield

CBFalconer said:
... snip about ggets and philosophies ...

But you've already done that! You just don't publicize it as much.

Well, that's kind of the point; if you wrote one of your very own,
presumably you'd be proud of it, so you'd publicise it like you publicise
ggets(), and that way, people would stand a fighting chance of getting to
choose between disposable and re-usable buffers.
 
G

Giorgos Keramidas

CBFalconer said:

Sure. So do all dynamically allocated buffers. But yours can't
be effectively re-used in the meantime. You need one allocation
per line, and there might be millions of lines.

It's not a misinterpretation of your intent. It's a criticism
of your design goals. :)

FWIW, it is not a very bad thing though.

<sort-of-off-topic-material>

System allocators for hosted C implementations have evolved up to
the point where they 'cache' recently allocated blocks, re-using
them for subsequent allocations without having to pay the full
overhead of grabbing new memory areas from the system.

In general, for lines of text that can fit in memory chunks which
tend to be small enough to be cached, a loop like:

char *line;

while ((line = grab_next_line()) != NULL) {
do_stuff(line);
free(line);
}

will usually run surprisingly fast :)

On the other hand, having a preallocated line buffer will not
incur the cost of malloc() & free() but will have to do some sort
of book-keeping for lines that are larger than the preallocated
area -- possibly resulting in more complex line-handling loops.

</sort-of-off-topic-material>
 
P

pete

Giorgos said:
FWIW, it is not a very bad thing though.

<sort-of-off-topic-material>

System allocators for hosted C implementations have evolved up to
the point where they 'cache' recently allocated blocks, re-using
them for subsequent allocations without having to pay the full
overhead of grabbing new memory areas from the system.

In general, for lines of text that can fit in memory chunks which
tend to be small enough to be cached, a loop like:

char *line;

while ((line = grab_next_line()) != NULL) {
do_stuff(line);
free(line);
}

will usually run surprisingly fast :)

On the other hand, having a preallocated line buffer will not
incur the cost of malloc() & free() but will have to do some sort
of book-keeping for lines that are larger than the preallocated
area -- possibly resulting in more complex line-handling loops.

</sort-of-off-topic-material>

I'm currently using line2string to read lines from text files.

/* BEGIN line2string.c */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int line2string(FILE *fp, char **line, size_t *size);

int main(void)
{
int rc;
char *buff_ptr;
size_t buff_size;

buff_size = 0;
buff_ptr = NULL;
puts("Enter any line of characters.");
rc = line2string(stdin, &buff_ptr, &buff_size);
while (rc > 1) {
printf("Your string is:\n%s\n", buff_ptr);
puts(
"\nJust hit the Enter key to end,\n"
"or enter any other line of characters to continue.");
rc = line2string(stdin, &buff_ptr, &buff_size);
}
free(buff_ptr);
return 0;
}

int line2string(FILE *fp, char **line, size_t *size)
{
int rc;
void *p;
size_t count;

count = 0;
for (rc = getc(fp); rc != EOF; rc = getc(fp)) {
++count;
if (count + 2 > *size) {
p = realloc(*line, count + 2);
if (p == NULL) {
if (*size > count) {
(*line)[count] = '\0';
(*line)[count - 1] = (char)rc;
} else {
ungetc(rc, fp);
}
count = 0;
break;
}
*line = p;
*size = count + 2;
}
if (rc == '\n') {
(*line)[count - 1] = '\0';
break;
}
(*line)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count > INT_MAX ? INT_MAX : count;
} else {
if (*size > count) {
(*line)[count] = '\0';
}
}
return rc;
}

/* END line2string.c */
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top