Re: Buffer or Realloc?
- From: Michael Mair <Michael.Mair@xxxxxxxxxxxxxxx>
- Date: Mon, 28 Aug 2006 07:37:13 +0200
bwaichu@xxxxxxxxx schrieb:
Is it generally better to set-up a buffer (fixed sized array) and read
and write to that
buffer even if it is larger than what is being written to it? Or is it
better to allocate memory and realloc it for the size of the what is
being written each time? In other words, what is the decision factor
between deciding to use a fixed size buffer or allocating memory
space and reallocing the size?
If it is conceivable that your "large enough" buffer can be
too small and if it is detrimental for your programme because
you caught this case but cannot handle whatever ought to be
in the buffer because of its lack of size, then consider
allocating and reallocating memory.
There are systems where you only have freestanding implementations,
i.e. lack <stdlib.h>. There, you obviously have to make do with
fixed size buffers.
I don't think the code below is optimal since the size of the "buffer"
becomes extremely small when I realloc it. I also spend time
re-allocating
it. And taking this to the next step, if I wrote to a linked list or a
red black
tree, I would have to allocate memory. In that case, how do I
determine
the best size?
Use a "reasonable" start size and choose a "reasonable"
minimum size.
"Reasonable" depends on your problem domain and the resources
you have at your beck and call.
Ideally, the allocated buffer is never resized at all but does
not claim a substantial amount of your memory.
Do not reallocate all the time; if you run into malloc()
failure somewhere else in your programme, then you could try
as fallback to resize allocated buffers to minimum and malloc()
again.
One thing to keep in mind: Try out your realloc() fallback for
very small initial buffer sizes and your error handling strategies
for very large initial buffer sizes (e.g. try to
malloc((size_t)-1)). Without test, the code is not worth anything
but as a show of goodwill...
Note: The code below contains some posix items. Please ignore those
items. I have also left out some error coding below as well.
The
below was written to just learn the regex API.
You could have left them out; providing compiling C code is your
best bet for getting good answers.
You forgot to
#include <stdlib.h>
#include <stdio.h>
int
main(void) {
regex_t preg;
char *string = strdup("hello1hello4hello2hello3 are you hello");
char *match;
regmatch_t pmatch[1];
size_t nmatch = 1;
size_t len = 0;
size_t offset = 0;
int test;
match = calloc(BUFSIZ, sizeof(char));
As you do not know the value of BUFSIZ, you might allocate
either 1 or one million bytes.
Go with a fixed initial value.
sizeof (char) always equals 1. If you want to base the allocation
on the type of match, then use
match = calloc(YOUR_INIT_BUFFER_SIZE, sizeof *match);
You also forgot to check whether calloc() succeeded. This is
outright stupid. No, I do not want to imply that you are stupid.
But it does not cost you anything to "prove" that you may go
on from here and failure to prove that may lead to a segmentation
fault at best and ungracious programme failure if an important
customer is standing right beside you together with your boss
on the other end of the scale.
if ( regcomp(&preg, "hello[41]", REG_BASIC) != 0)
perror("regcomp failed");
while (string[offset] != '\0') {
test = regexec((const regex_t *)&preg, &string[offset],
nmatch, pmatch,0);
if (test == REG_NOMATCH || test !=0) {
break;
}
len = pmatch[0].rm_eo-pmatch[0].rm_so;
/* is this optimal or should I use a fixed sized buffer? */
match = realloc(match, len+1);
Once again, you discount the possibility of allocation failure.
The right way is
char *tmp;
....
tmp = realloc(match, len+1);
if (tmp == 0) {
/* Your error handling here; match is still available */
}
match = tmp;
You believe that there is no bug in the regex functions.
This is very trustful and certainly honours the writers of that
library -- however, if len is assigned a negative value
(which becomes a large positive value), then you may run
out of memory or inadvertently free(match) if len+1 == 0.
This is the part I meant above: Write a fallback and test it.
This is no paranoia but
- good practice for you; recovering gracefully from a malloc()
failure is hard
- may help you catch hard-to-catch bugs
- makes other people trust _your_ code -- if I evaluate code
and find it to be of the "malloc() always succeeds variety",
I am less than impressed.
strlcpy(match, &string[offset],
len+1);
(void)printf("matched string: %s\n", match);
offset += pmatch[0].rm_eo;
}
(void)printf("original string: %s\n", string);
free(match);
regfree(&preg);
exit(0);
}
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
.
- Follow-Ups:
- Re: Buffer or Realloc?
- From: bwaichu@xxxxxxxxx
- Re: Buffer or Realloc?
- References:
- Buffer or Realloc?
- From: bwaichu@xxxxxxxxx
- Buffer or Realloc?
- Prev by Date: Re: How can I create a Ram Disk within C/C++ program?
- Next by Date: Re: Buffer or Realloc?
- Previous by thread: Buffer or Realloc?
- Next by thread: Re: Buffer or Realloc?
- Index(es):
Relevant Pages
|