Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #163420 > unrolled thread
| Started by | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| First post | 2021-11-12 15:48 -0300 |
| Last post | 2021-11-19 16:07 -0300 |
| Articles | 15 on this page of 75 — 20 participants |
Back to article view | Back to comp.lang.c
on why declare a struct with a single array in it Meredith Montgomery <mmontgomery@levado.to> - 2021-11-12 15:48 -0300
Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-12 19:56 +0100
Re: on why declare a struct with a single array in it Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-12 19:31 +0000
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-12 21:07 +0100
Re: on why declare a struct with a single array in it pozz <pozzugno@gmail.com> - 2021-11-18 15:53 +0100
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-18 16:13 +0100
Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-18 16:26 +0100
Re: on why declare a struct with a single array in it pozz <pozzugno@gmail.com> - 2021-11-18 17:22 +0100
Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-18 18:04 +0100
Re: on why declare a struct with a single array in it Meredith Montgomery <mmontgomery@levado.to> - 2021-11-19 16:00 -0300
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-18 22:58 +0100
Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-19 17:53 +0100
Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-19 11:27 -0800
Re: on why declare a struct with a single array in it scott@slp53.sl.home (Scott Lurndal) - 2021-11-19 20:46 +0000
Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-19 12:52 -0800
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-20 13:36 +0100
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-20 14:49 +0000
Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-20 15:52 -0800
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 00:19 +0000
Re: on why declare a struct with a single array in it Richard Damon <Richard@Damon-Family.org> - 2021-11-20 20:44 -0500
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-21 14:51 +0100
Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-21 19:32 +0100
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-21 21:51 +0100
Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-22 03:17 +0100
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-22 11:31 +0100
Re: on why declare a struct with a single array in it Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-10 04:21 -0800
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-12-10 14:43 +0100
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-22 11:56 +0000
Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-10 01:47 -0800
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-12-10 10:55 +0000
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-12-10 14:51 +0100
Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-11 06:56 -0800
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-12-11 16:04 +0000
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-12-11 17:23 +0000
Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-21 05:30 -0800
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2022-01-21 13:49 +0000
Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-11 12:17 -0800
Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-12 13:00 +0000
Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-12 08:25 -0800
Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-12 17:38 +0000
Re: on why declare a struct with a single array in it Dick <thiebauddick2@aol.com> - 2021-12-12 16:19 -0500
Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-13 08:06 +0000
Re: on why declare a struct with a single array in it Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-13 01:30 -0800
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-12-13 09:34 +0100
Re: on why declare a struct with a single array in it Robert Latest <boblatest@yahoo.com> - 2021-12-13 18:53 +0000
Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-13 20:38 +0000
Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-15 00:38 -0800
Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-15 11:21 +0000
Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-15 10:26 -0800
Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-15 10:45 -0800
Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-10 10:52 -0800
Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-22 04:06 +0100
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-22 11:32 +0000
Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-22 13:00 -0800
Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-21 13:08 -0800
Re: on why declare a struct with a single array in it Richard Damon <Richard@Damon-Family.org> - 2021-11-20 20:44 -0500
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 12:22 +0000
Re: on why declare a struct with a single array in it Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2021-11-20 20:13 -0700
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 12:35 +0000
Re: on why declare a struct with a single array in it Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2021-11-21 10:53 -0700
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 18:49 +0000
Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-21 13:04 -0800
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 14:42 +0000
Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-21 01:34 +0100
Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 00:48 +0000
Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-20 16:58 -0800
Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-21 14:40 +0100
Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-21 12:59 -0800
Re: on why declare a struct with a single array in it scott@slp53.sl.home (Scott Lurndal) - 2021-11-21 15:58 +0000
Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-11-20 10:55 +0000
Re: on why declare a struct with a single array in it Jorgen Grahn <grahn+nntp@snipabacken.se> - 2021-11-13 08:47 +0000
Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-13 18:23 +0100
Re: on why declare a struct with a single array in it Kaz Kylheku <480-992-1380@kylheku.com> - 2021-11-13 17:55 +0000
Re: on why declare a struct with a single array in it Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-11-19 13:14 +0300
Re: on why declare a struct with a single array in it Meredith Montgomery <mmontgomery@levado.to> - 2021-11-19 16:07 -0300
Page 4 of 4 — ← Prev page 1 2 3 [4]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-11-21 18:49 +0000 |
| Message-ID | <sne4cd$un$1@dont-email.me> |
| In reply to | #163551 |
On 21/11/2021 17:53, Joe Pfeiffer wrote: > Bart <bc@freeuk.com> writes: >> On 21/11/2021 03:13, Joe Pfeiffer wrote: >>> Bart <bc@freeuk.com> writes: >>>> >>>> If an application needs to allocate 100 million 32-byte nodes, which >>>> would occupy 3.2GB by themselves, how much extra would be needed for >>>> the size, 'just for checking'? >>> If that's what you're doing, you shouldn't be using malloc() for the >>> individual nodes. >> >> Why not; isn't that exactly what it's for? > > Because it isn't optimized for a use case like that. It's a general > purpose allocator, and you're using it for a situation that's 'way out > on the fringes. > >> And what is the alternative, to create a custom allocator? > > Yes. When I've had similar situations I've allocated large blocks with > malloc() and then allocated my little blocks from the big ones. I would expect the majority of allocs in an application (not total memory used) are going to be small: * Numbers of instances of identical struct types, across many types * Allocation of short strings Yet all these common uses, where overheads are likely to more significant, are considered to be 'on the fringes'? With strings in particular, the allocator holds info about the string length (or its allocated size), then would be useful to an application, yet there is no way to make use of that information in the application. Which leads to the situation that for a C++-style expandable string or vector, the necessary descriptor needs to maintain its own duplicate of the 'allocated' size. (Actually there will be the current length, the requested capacity, which are known, and the space actually allocated by malloc, which is unknown; plus the metadata it needs.) It all seems rather wasteful.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-11-21 13:04 -0800 |
| Message-ID | <snec8p$og6$1@dont-email.me> |
| In reply to | #163545 |
On 11/21/2021 4:35 AM, Bart wrote: > On 21/11/2021 03:13, Joe Pfeiffer wrote: >> Bart <bc@freeuk.com> writes: >> >>> On 20/11/2021 23:52, Keith Thompson wrote: >>>> David Brown <david.brown@hesbynett.no> writes: >>>>> On 19/11/2021 21:52, Keith Thompson wrote: >>>> [...] >>>>>> Perhaps -- but typically that information is not stored in the >>>>>> pointer >>>>>> itself. If it were, all void* values would have to store that extra >>>>>> information. >>>>>> >>>>>> (I think it's easier to store bookkeeping data before the allocated >>>>>> space. If you store it after the space, it's hard to know where >>>>>> it is.) >>>>> >>>>> That's the most common way for a simple malloc/free system. >>>>> >>>>> It has always struck me as a mistake that C did things that way - >>>>> in my >>>>> opinion, "free" should have taken an additional parameter of the size >>>>> for the deallocation. >>>> Meh. That would have introduced another rich source of programming >>>> errors (passing the wrong size). >>> >>> You could also pass the wrong size to malloc, or the wrong pointer to >>> free. >>> >>>> Probably most implementations would >>>> have kept track of the size anyway, so they could detect errors. >>> >>> I doubt that, unless it's for debugging mode. >>> >>> If an application needs to allocate 100 million 32-byte nodes, which >>> would occupy 3.2GB by themselves, how much extra would be needed for >>> the size, 'just for checking'? >> >> If that's what you're doing, you shouldn't be using malloc() for the >> individual nodes. > > Why not; isn't that exactly what it's for? > > And what is the alternative, to create a custom allocator? > >>> On my machine that seems to be 16 bytes per node, so 50% more. 1.6GB >>> extra just so someone can write: >>> >>> free(p); >>> >>> instead of: >>> >>> free(p, sizeof(treenode)); >>> >>> possibly in just one place in the program. >>> >>> It doesn't make sense. >> >> Remember, you have to have all the data structures to keep track of the >> allocated space so malloc() will work. > > Everyone is saying this; no one is explaining exactly why it needs to! > > Are you saying that, unless an allocated block is tagged with a size, > malloc has no idea which pool memory has been allocated and which hasn't? free can round its address down to a boundary, and get at a header from there. Therefore it can find its freelist, or pool, or whatever... > > I've written a few allocators over the years, they have never needed to > record the size of a block. >
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-11-21 14:42 +0000 |
| Message-ID | <sndls8$r20$1@dont-email.me> |
| In reply to | #163534 |
On 21/11/2021 00:19, Bart wrote:
> On 20/11/2021 23:52, Keith Thompson wrote:
>> Probably most implementations would
>> have kept track of the size anyway, so they could detect errors.
>
> I doubt that, unless it's for debugging mode.
>
> If an application needs to allocate 100 million 32-byte nodes, which
> would occupy 3.2GB by themselves, how much extra would be needed for the
> size, 'just for checking'?
>
> On my machine that seems to be 16 bytes per node, so 50% more. 1.6GB
> extra just so someone can write:
>
> free(p);
>
> instead of:
>
> free(p, sizeof(treenode));
>
> possibly in just one place in the program.
That last example (which would have been a Binary Trees benchmark) could
also be written as:
free(p, sizeof(*p));
If p has type T* and you know the allocation is for exactly one such
object (eg. as AST node in a compiler), then you don't need the
allocator to keep track of the size.
I usually go to some trouble to craft my struct sizes to be
powers-of-to, and it would be annoying for an allocator to just add its
own garbage on top.
(Here are the two lines from Binary Trees in my language (not using C as
I don't have my pcm library there) that handle memory:
t := malloc(treenode.bytes)
free(tree)
that's when I use C routines directly. If I switch to a different
allocator that I normally use within my interpreters, it looks like this:
t := pcm_alloc(treenode.bytes)
pcm_free(tree, treenode.bytes) # or tree^.bytes
Either work. Except that malloc/free [**] take 11 seconds for one run.
My pcm_alloc/pcm_free take 3.7 seconds, nearly 3 times as fast.
Although the reason for that is probably not the extra memory, as the
node size of 24 bytes is allocated 32 bytes in both cases: with malloc
because of the size overhead; in mine because it's rounded up to a
power-of-two.
My allocator is probably just simpler...
---------------
** Using malloc/free from msvcrt.dll.
C version using malloc/free and gcc-O3 takes 10.3 seconds, likely using
same library.
C version on WSL and with gcc-O3 takes 4.8 seconds.
However, if I port my language using those pcm calls to C, then I get
timings of 2.7 seconds on Windows, and 2.1 seconds on WSL, using gcc-O3.)
)
[toc] | [prev] | [next] | [standalone]
| From | Guillaume <message@bottle.org> |
|---|---|
| Date | 2021-11-21 01:34 +0100 |
| Message-ID | <snc47j$12d0$1@gioia.aioe.org> |
| In reply to | #163533 |
Le 21/11/2021 à 00:52, Keith Thompson a écrit : > David Brown <david.brown@hesbynett.no> writes: >> On 19/11/2021 21:52, Keith Thompson wrote: > [...] >>> Perhaps -- but typically that information is not stored in the pointer >>> itself. If it were, all void* values would have to store that extra >>> information. >>> >>> (I think it's easier to store bookkeeping data before the allocated >>> space. If you store it after the space, it's hard to know where it is.) >> >> That's the most common way for a simple malloc/free system. >> >> It has always struck me as a mistake that C did things that way - in my >> opinion, "free" should have taken an additional parameter of the size >> for the deallocation. > > Meh. That would have introduced another rich source of programming > errors (passing the wrong size). Yes absolutely. Besides, the extra data allocated for each malloc() is a bunch of stuff to identify the chain of allocated blocks, so this extra data is needed anyway.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-11-21 00:48 +0000 |
| Message-ID | <snc51m$epu$1@dont-email.me> |
| In reply to | #163535 |
On 21/11/2021 00:34, Guillaume wrote: > Le 21/11/2021 à 00:52, Keith Thompson a écrit : >> David Brown <david.brown@hesbynett.no> writes: >>> On 19/11/2021 21:52, Keith Thompson wrote: >> [...] >>>> Perhaps -- but typically that information is not stored in the pointer >>>> itself. If it were, all void* values would have to store that extra >>>> information. >>>> >>>> (I think it's easier to store bookkeeping data before the allocated >>>> space. If you store it after the space, it's hard to know where it >>>> is.) >>> >>> That's the most common way for a simple malloc/free system. >>> >>> It has always struck me as a mistake that C did things that way - in my >>> opinion, "free" should have taken an additional parameter of the size >>> for the deallocation. >> >> Meh. That would have introduced another rich source of programming >> errors (passing the wrong size). > > Yes absolutely. Besides, the extra data allocated for each malloc() is a > bunch of stuff to identify the chain of allocated blocks, so this extra > data is needed anyway. > Why for allocated blocks? The chain of freed blocks would be more relevant, and there you can just use the freed data space.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-11-20 16:58 -0800 |
| Message-ID | <snc5jo$fq4$1@dont-email.me> |
| In reply to | #163535 |
On 11/20/2021 4:34 PM, Guillaume wrote: > Le 21/11/2021 à 00:52, Keith Thompson a écrit : >> David Brown <david.brown@hesbynett.no> writes: >>> On 19/11/2021 21:52, Keith Thompson wrote: >> [...] >>>> Perhaps -- but typically that information is not stored in the pointer >>>> itself. If it were, all void* values would have to store that extra >>>> information. >>>> >>>> (I think it's easier to store bookkeeping data before the allocated >>>> space. If you store it after the space, it's hard to know where it >>>> is.) >>> >>> That's the most common way for a simple malloc/free system. >>> >>> It has always struck me as a mistake that C did things that way - in my >>> opinion, "free" should have taken an additional parameter of the size >>> for the deallocation. >> >> Meh. That would have introduced another rich source of programming >> errors (passing the wrong size). > > Yes absolutely. Besides, the extra data allocated for each malloc() is a > bunch of stuff to identify the chain of allocated blocks, so this extra > data is needed anyway. > It is not needed in some allocators. I have coded them with basically zero overhead. Actually, only allocations less than sizeof(void*) are padded up to the size of a pointer...
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-21 14:40 +0100 |
| Message-ID | <sndi8b$3ht$1@dont-email.me> |
| In reply to | #163533 |
On 21/11/2021 00:52, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 19/11/2021 21:52, Keith Thompson wrote: > [...] >>> Perhaps -- but typically that information is not stored in the pointer >>> itself. If it were, all void* values would have to store that extra >>> information. >>> >>> (I think it's easier to store bookkeeping data before the allocated >>> space. If you store it after the space, it's hard to know where it is.) >> >> That's the most common way for a simple malloc/free system. >> >> It has always struck me as a mistake that C did things that way - in my >> opinion, "free" should have taken an additional parameter of the size >> for the deallocation. > > Meh. That would have introduced another rich source of programming > errors (passing the wrong size). Probably most implementations would > have kept track of the size anyway, so they could detect errors. As > long as they're keeping track, why make the user do so as well? It would have lead to some different programming errors, perhaps, but I don't think it would have lead to more. If you are at the point in your code where you can correctly call "free(p);", it seems highly unlikely that you don't also have the size of the allocation there too. (To be clear, I expect you to have the size used when calling malloc - if the heap implementation rounds that up to a block size in some way, then it would do the same for sized free.) You know the size used in your malloc() call. Either you are getting space for a single object (such as a large struct), or an array - and you know the size when you are using the object or array later. There may be some occasions when a little extra effort is needed on the part of the programmer to keep track of the size before calling free(), but I believe that would be a minority of cases. > > Perhaps a lower-level allocator might be more efficient if user code is > required to keep track, but I don't think it would be all that useful > for most applications. > It can easily make a big difference when you consider caches and pages. A cache line might be 32 bytes long, or more - either your data is badly aligned, or that's a lot of wasted space just to hold a size that the client code already knows. If you've got a tree structure where the node data (including pointers to branches) all fit within a 32 byte block, half the space in your cache is wasted holding the sizes for "free". For bigger cache lines, either you waste even more space per allocation or your sizes (within their 16 or 32 byte alignment block) are mixed with the data that you actually /want/ in your cache. However you do it, it can be a serious waste of cache space. The alternative is to have more advanced heap management algorithms which keep the size information independently, meaning they have to support a mapping between allocated addresses and the size allocated. This is complex, slow and inefficient compared to a structure where the client code has the size - all you need then might be a plain bitmap with a single bit per used block (with pools to deal efficiently with different sizes of allocation). Storing the size of an allocation as an extra item before the block was a simple and efficient mechanism in earlier computers - but not now. There are, of course, many ways to implement a heap with different balances of complexity, speed, efficiency, etc. Storing the size somewhere does not make them simpler, faster or more efficient. C++14 introduced sized deletion so that you can make allocators that don't need to track sizes.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-11-21 12:59 -0800 |
| Message-ID | <snebus$mv8$1@dont-email.me> |
| In reply to | #163546 |
On 11/21/2021 5:40 AM, David Brown wrote: > On 21/11/2021 00:52, Keith Thompson wrote: >> David Brown <david.brown@hesbynett.no> writes: >>> On 19/11/2021 21:52, Keith Thompson wrote: >> [...] >>>> Perhaps -- but typically that information is not stored in the pointer >>>> itself. If it were, all void* values would have to store that extra >>>> information. >>>> >>>> (I think it's easier to store bookkeeping data before the allocated >>>> space. If you store it after the space, it's hard to know where it is.) >>> >>> That's the most common way for a simple malloc/free system. >>> >>> It has always struck me as a mistake that C did things that way - in my >>> opinion, "free" should have taken an additional parameter of the size >>> for the deallocation. >> >> Meh. That would have introduced another rich source of programming >> errors (passing the wrong size). Probably most implementations would >> have kept track of the size anyway, so they could detect errors. As >> long as they're keeping track, why make the user do so as well? > > It would have lead to some different programming errors, perhaps, but I > don't think it would have lead to more. If you are at the point in your > code where you can correctly call "free(p);", it seems highly unlikely > that you don't also have the size of the allocation there too. (To be > clear, I expect you to have the size used when calling malloc - if the > heap implementation rounds that up to a block size in some way, then it > would do the same for sized free.) > > You know the size used in your malloc() call. Either you are getting > space for a single object (such as a large struct), or an array - and > you know the size when you are using the object or array later. [...] Fwiw, I am quite fond of creating a big chunk of memory, and aligning it on a "large" boundary. Say 4096*4 bytes... Now, every address in the memory can be rounded down to get at the boundary. There is a structure sitting right before this boundary, a header: [header][aligned_memory] Every memory allocation less than the size of a pointer, is rounded up to the size of a pointer. So, on a 32-bit system, 0...3 are rounded up to 4. That's it. Now, wrt freeing something, we take the address, round down to boundary, subtract the header, then we are at the header that can contain a free list to link the pointer in. It's quite nice, and can be on a per-thread basis. headers per-thread... ;^)
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-11-21 15:58 +0000 |
| Message-ID | <W0umJ.116417$IW4.4067@fx48.iad> |
| In reply to | #163513 |
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes: >scott@slp53.sl.home (Scott Lurndal) writes: >> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes: >>>Guillaume <message@bottle.org> writes: >>>> Le 18/11/2021 à 22:58, David Brown a écrit : >> >>>> Now there are kind of exceptions to that, but that are purely >>>> "hand-implemented" and have nothing to do with the language itself: >>>> for instance, the typical malloc() behavior. Behind the scenes, >>>> pointers returned by malloc() are "fat pointers", and you can also >>>> implement your own fat pointers if you so wish. But the language >>>> doesn't care. It has no provision for that, except you can do pointer >>>> arithmetics to your heart's content. >>> >>>I'm not sure what you mean about malloc() returning "fat pointers". >>>malloc() returns a void* with no information about the size or type of >>>what it points to. Some implementations might provide a way to query >>>the size of the allocated space, but that's not standard. >> >> Many malloc implementations reserve additional space, either before >> or after the allocated space for bookkeeping and alignment purposes. >> >> Perhaps that is the source of Guillaume's "fat pointer" reference. > >Perhaps -- but typically that information is not stored in the pointer >itself. If it were, all void* values would have to store that extra >information. True. The only modern fat pointers I'm aware of (at least that I can talk about publically) are the Burroughs B6500 family processors (capabilities) and the CHERI project. > >(I think it's easier to store bookkeeping data before the allocated >space. If you store it after the space, it's hard to know where it is.) Point.
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2021-11-20 10:55 +0000 |
| Message-ID | <snak7r$rj09$2@news.xmission.com> |
| In reply to | #163512 |
In article <Y2UlJ.79170$ya3.75666@fx38.iad>, Scott Lurndal <slp53@pacbell.net> wrote: ... >>I'm not sure what you mean about malloc() returning "fat pointers". >>malloc() returns a void* with no information about the size or type of >>what it points to. Some implementations might provide a way to query >>the size of the allocated space, but that's not standard. > >Many malloc implementations reserve additional space, either before >or after the allocated space for bookkeeping and alignment purposes. > >Perhaps that is the source of Guillaume's "fat pointer" reference. That's the way I took it. That, although not in the standard, and thus completely outside of Keith's field of vision, that on most implementations you can "reverse engineer" how your particular implementation of malloc (and friends) works, and figure out how to use the data contained around the pointer value returned by malloc to figure out things like how big the malloc'd region is. Totally non-portable, of course, but necessary in certain situations. -- It's possible that leasing office space to a Starbucks is a greater liability in today's GOP than is hitting your mother on the head with a hammer.
[toc] | [prev] | [next] | [standalone]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2021-11-13 08:47 +0000 |
| Message-ID | <slrnsouusf.1rfm.grahn+nntp@frailea.sa.invalid> |
| In reply to | #163420 |
On Fri, 2021-11-12, Meredith Montgomery wrote:
> Why would someone put a lonely array inside a structure?
>
> struct ip_address { unsigned char d[4]; };
Or the official Unix IPv6 address:
struct in6_addr {
unsigned char s6_addr[16]; /* IPv6 address */
};
> Would it be because they want to (in the future) add more members to
> this structure?
Not in this case -- noone will ever change the definition of "an IPv4
address". I hope.
> Because it's not like they can hide this array in the
> structure; it's still referenced as
>
> struct ip_address ip;
> ip.d[0] = ...
> ip.d[1] = ...
>
> But it does look neat, so I guess neatness is the reason? It's also
> easier to read because we're constantly reminded it is an ip address?
Others have already replied; I will give a similar answer.
I use this pattern all the time, whenever I can, i.e. when it's ok that
all arrays are the same length[0]. The benefits are:
- I get a real, distinct type with a name, which doesn't convert or
decay to other types. struct in6_addr isn't just /any/ array of 16
unsigned chars: it's an IPv6 address.
- I get objects which work like any other objects in assignments,
function calls and so on.
There is no information hiding, but that's not a big problem IMO. Or
perhaps I have gotten used to it.
/Jorgen
[0] And when the length is variable you can sometimes do
struct foo {
struct bar v[31];
unsigned count;
};
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
[toc] | [prev] | [next] | [standalone]
| From | Guillaume <message@bottle.org> |
|---|---|
| Date | 2021-11-13 18:23 +0100 |
| Message-ID | <smosat$1qgm$1@gioia.aioe.org> |
| In reply to | #163425 |
Le 13/11/2021 à 09:47, Jorgen Grahn a écrit : > On Fri, 2021-11-12, Meredith Montgomery wrote: >> Because it's not like they can hide this array in the >> structure; it's still referenced as (...) > There is no information hiding, but that's not a big problem IMO. Or > perhaps I have gotten used to it. Actually, I didn't mention it, but encapsulating data in a struct does allow some form of "information hiding" - if we all mean the same thing here. You can define "opaque" types using structs - more precisely, using pointers to structs. It's commonly seen in standard libraries, POSIX stuff, etc. Of course, if you have access to the struct definition, there is no hiding per se, but you can absolutely distribute a library with only opaque data types for the user of the library. 'FILE *' is a common example. Do you ever care what is behind a FILE type? It often depends on the platform anyway. You only use it through a pointer. What allows to hide what's inside a struct in C using pointers is the fact you can absolutely define a pointer to a struct without defining the struct itself: typedef struct Foo * Foo_t; As long as you don't need to directly access the underlying struct members, that works plenty fine - typical use is through function calls.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| Date | 2021-11-13 17:55 +0000 |
| Message-ID | <20211113094911.939@kylheku.com> |
| In reply to | #163420 |
On 2021-11-12, Meredith Montgomery <mmontgomery@levado.to> wrote:
> Why would someone put a lonely array inside a structure?
>
> struct ip_address { unsigned char d[4]; };
The main reason is because structs provide more abstraction than
arrays in C.
You can assign them, pass them into functions and return them.
If you have
typedef struct ip_address ip_address_t;
this ip_address_t type will not do weird things, like if it were an
array typedef; it will not turn into a pointer when you use it to
declare a function parameter, or produce object definitions that
cannot be assigned.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [prev] | [next] | [standalone]
| From | Anton Shepelev <anton.txt@g{oogle}mail.com> |
|---|---|
| Date | 2021-11-19 13:14 +0300 |
| Message-ID | <20211119131443.1ff9e003959ec0d0e5db4cc7@g{oogle}mail.com> |
| In reply to | #163420 |
Meredith Montgomery:
> Why would someone put a lonely array inside a structure?
>
> struct ip_address { unsigned char d[4]; };
Here is a comment on that matter from the maintainer of the
Netpbm project. This is from a private e-mail, but I hope he
will not object to publishing of this quotation:
And one somewhat more substantial thing: t_float3
(Float3) should be a struct containing a double[] rather
than just a double[]. That way you don't have confusing
degeneration to a pointer when you pass it to a function
and it becomes obvious what the outputs of a function are
(because they're explicit pointers to the struct).
--
() ascii ribbon campaign - against html e-mail
/\ http://preview.tinyurl.com/qcy6mjc [archived]
[toc] | [prev] | [next] | [standalone]
| From | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| Date | 2021-11-19 16:07 -0300 |
| Message-ID | <86ee7cklpt.fsf@levado.to> |
| In reply to | #163490 |
Anton Shepelev <anton.txt@g{oogle}mail.com> writes:
> Meredith Montgomery:
>
>> Why would someone put a lonely array inside a structure?
>>
>> struct ip_address { unsigned char d[4]; };
>
> Here is a comment on that matter from the maintainer of the
> Netpbm project. This is from a private e-mail, but I hope he
> will not object to publishing of this quotation:
>
> And one somewhat more substantial thing: t_float3
> (Float3) should be a struct containing a double[] rather
> than just a double[]. That way you don't have confusing
> degeneration to a pointer when you pass it to a function
> and it becomes obvious what the outputs of a function are
> (because they're explicit pointers to the struct).
Interesting. That seems point 2 written in Message-ID
<sn8kq9$tep$1@gioia.aioe.org>
Thanks for sharing.
[toc] | [prev] | [standalone]
Page 4 of 4 — ← Prev page 1 2 3 [4]
Back to top | Article view | comp.lang.c
csiph-web