Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- From: "Bill Reid" <hormelfree@xxxxxxxxxxxxxxxx>
- Date: Fri, 11 Aug 2006 14:45:07 GMT
Keith Thompson <kst-u@xxxxxxx> wrote in message
news:lnk65fydta.fsf@xxxxxxxxxxxxxxxxxx
"Bill Reid" <hormelfree@xxxxxxxxxxxxxxxx> writes:some
Barry Schwarz <schwarzb@xxxxxxxxx> wrote in message
news:k93od21vgd6n6fhrg6tooem3r5j06ejrq4@xxxxxxxxxx
On Fri, 11 Aug 2006 03:54:19 GMT, "Bill Reid"
<hormelfree@xxxxxxxxxxxxxxxx> wrote:
Bear with me, as I am not a "professional" programmer, but I was
working on part of program that reads parts of four text files into
a buffer which I re-allocate the size as I read each file. I read
andYeah, it's a little confusing, and not that relevant to what I'mof the items from the bottom up of the buffer, and some from the
top down, moving the bottom items back to the new re-allocated
bottom on every file read.
I don't quite follow this description.
asking...the
bottom line is I want to separately sort two parts of a list...
Then when I've read all four files, I sort the top and bottom items
separately using qsort(), which takes a pointer to a list of items,
Well, OK, maybe, here's canonical specificity:write the two sorted lists to two new files.
Problem is, I worry that if I just supply a pointer to the first item
in the bottom list to qsort(), it might point out to bozo-land during
the sort because I thought that dynamically re-allocated memory
is not necessarily contiguous. So I've done a little two step where
The block of memory whose non-NULL address is returned from
malloc/realloc/calloc is guaranteed to be contiguous.
OK, that's the answer, I was just plain wrong that the memory
might not be contiguous...I've probably only read that guarantee
about 100000000000 times but just forgot it.
I think I got that confused with the idea that the re-allocated
block may have a different location than the original malloc, which
would mean...
One thing that I found a little confusing in your original message is
that you talked about "re-allocated" memory, but you didn't mention
the "realloc" function. The more specific your description, the more
likely it is that we can help.
/* now re-allocate memory for the instrument strings */
if((curr_instrs=(instr_strs *)
realloc(curr_instrs,num_instrs*sizeof(instr_strs)))==NULL) {
printf("Not enough memory for instruments buffer\n");
goto CloseFiles;
}
Does that help you help me?
[...]*)curr_instrs+num_symbols,num_no_symbols,128,sort_alpha_list);
OK, so this should be completely legal and flawless:
/* sort the symbol list alphabetically */
qsort((void *)curr_instrs,num_symbols,128,sort_alpha_list);
then...
/* sort the no-symbol list alphabetically */
qsort((void
By "legal and flawless" I DID mean "100% guaranteed functional",
Um, no.
not "pleasing to thine eyes"...
Don't be afraid of whitespace. I put blanks around most operatorThat's the way YOU'D do it, I do it differently, and since I'm the only
symbols, and after every comma. If I have to split something across
lines, that's ok. So I'd write your qsort call as:
qsort((void *)curr_instrs + num_symbols,
num_no_symbols,
128,
sort_alpha_list);
one reading it (except in this one rare instance, or occasionally I'll post
some code somewhere on the net), I can read it just fine, and of
course it compiles all the same...
The third argument, 128, is a "magic number". It's very difficult to
tell what it means or whether it's even correct. Define a constant:
#define WHATEVER 128
In qsort(), it's basically 128 (character) bytes.
I've actually got "128" defined globally (and I do mean globally, for
several hundred thousand lines of code) for the purposes of reading
and writing strings of certain lengths. And those damned defines
have managed to screw me up royally several times, including a
really irritating "intermittent" problem I had when I first wrote this
particular section of code. So lately I've been using them less
and less...
so you only need to change it in one place (but pick a better name, ofEven at file scope right now I'm more comfortable with the way it
course).
is...
The first argument to qsort is:Then how does qsort() do it? I'm assuming now that it must just
(void *)curr_instrs + num_symbols
You can't do pointer arithmetic on a void* value. (Some compilers may
allow it; if you're using gcc, try "-ansi -pedantic -Wall -W", or
replace "-ansi" with "-std=c99").
use pointer arithmetic internally, because it doesn't seem to want or
recognize my typedef of a 128-character string:
typedef char instr_strs[128];
instr_strs *curr_instrs;
If you're trying to get the address pointed to by curr_instrs plus an
offset of num_symbols bytes, you'll need to to the arithmetic using
char*:
qsort((char*)curr_instrs + num_symbols,
/* other args */);
assuming that curr_instrs isn't already a char*.
Nope, a pointer to the first of many 128-character strings, as above, so
are you saying the pointer cast should be (instr_strs *)? I have no problem
with that, as long as it works, and I must stress again at this point that
the current code:
/* sort the symbol list alphabetically */
qsort((void *)curr_instrs,num_symbols,128,sort_alpha_list);
Has worked flawlessly for months now; it's part of a particular section
of code that downloads about 3/4 meg of raw data from the net every
day at a specific time, parses out about 100,000 data items, and writes
them to a custom database in a matter of seconds.
The only reason I asked the original question was because I went
back and reviewed the code and wondered if I could shave a few
more milliseconds off the execution time...
Note that I didn't
cast the expression to void*; any pointer-to-object type can beYeah, I noticed that, I just use (void *) because that's what
converted to void*, or vice versa.
I thought qsort() wanted, and it definitely WORKS that way
(I've used qsort() dozens of times EXACTLY that way without
problems).
Now to get back to this:
If you're trying to get the address pointed to by curr_instrs plus an
offset of num_symbols bytes, you'll need to to the arithmetic using
char*:
qsort((char*)curr_instrs + num_symbols,
/* other args */);
I think I see what you're saying, maybe...and maybe not...
If curr_instrs is pointer to a 128-character string type, wouldn't
curr_instrs+num_symbols then point to a location offset from
curr_instrs by (num_symbols*128 bytes)? And if so, what's
the point of cast (char *) if qsort() already works by sorting
some specified number of sequences of some specified
number of character bytes?
I thought I had the answer to my original question, and then it
slipped away from me...
---
William Ernest Reid
.
- References:
- Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- From: Bill Reid
- Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- From: Barry Schwarz
- Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- From: Bill Reid
- Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- From: Keith Thompson
- Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- Prev by Date: Re: C99 stdint.h
- Next by Date: Re: Natural size: int
- Previous by thread: Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- Next by thread: Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
- Index(es):
Relevant Pages
|