- Why does vector::reserve() not grow exponentially ? - 22 Updates
- good reference on threads - 2 Updates
- Google Groups (was Re: differential reference counting...) - 1 Update
| Bonita Montero <Bonita.Montero@gmail.com>: Jun 11 01:16PM +0200 > Just because something isn't specified for a library class, doesn't mean > that the implementation is prohibited from having it. The containers _always_ use allocators that provide the allocatotor -interface which is specified under the link I've shown you. And with this there is no opportunity to get the size of the memory actually allocated. |
| Bonita Montero <Bonita.Montero@gmail.com>: Jun 11 01:17PM +0200 > The allocator API may not tell you when an allocator actually gets more > memory than you ask for. But containers like std::vector are part of > the standard library - they are not restricted to the public API. ... They are because they're restricted to the specified behaviour of the allocator template-parameter. |
| Paavo Helde <myfirstname@osa.pri.ee>: Jun 11 02:18PM +0300 > } > return 0; > } It definitely does not work fine with gcc: > g++ test1.cpp -D_GLIBCXX_DEBUG > ./a.exe /usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/debug/vector:427: In function: std::__debug::vector<_Tp, _Allocator>::reference std::__debug::vector<_Tp, _Allocator>::operator[](std::__debug::vector<_Tp, _Allocator>::size_type) [with _Tp = int; _Allocator = std::allocator<int>; std::__debug::vector<_Tp, _Allocator>::reference = int&; std::__debug::vector<_Tp, _Allocator>::size_type = long unsigned int] Error: attempt to subscript container with out-of-bounds index 0, but container only holds 0 elements. Objects involved in the operation: sequence "this" @ 0x0xffffcbf0 { type = std::__debug::vector<int, std::allocator<int> >; } Aborted (core dumped) Note: the -D_GLIBCXX_DEBUG flag is what you want to use to check that your code is correct. |
| Bonita Montero <Bonita.Montero@gmail.com>: Jun 11 01:19PM +0200 > that even if you request to reserve 8388492 bytes of memory, it's better > to allocate an even 8388608 bytes. If so, it makes perfect sense to > adjust the number of reserved values to reflect reality. That's not what we're talking about. We're talking about if any container can notice the size actually allocated by an allocator - it can't. Even with the malloc()-API there's no opportunity to get the real size of the block. |
| Manfred <noname@add.invalid>: Jun 11 01:22PM +0200 >> You mean "seems to work", which is one possible effect of UB. > Does work. There's no reason why it wouldn't unless you can think of one. Memory allocated via resize() involves /construction/ of the required objects - i.e. invocation of their constructor via e.g. placement new. On the contrary, reserve() allocates memory but does /not/ construct the objects. It is UB to access objects before their construction. >> of reserve(10). >> What is the problem? > Why does it need both? What is the point of reserve() is my point. See above. |
| Paavo Helde <myfirstname@osa.pri.ee>: Jun 11 02:26PM +0300 > complex interactions with default or user methods that could easily cause a > crash if you try and use any of them when uninitialised. Yes, it'll probably > be some random value but it won't crash. Yet another flat-earther who thinks his beliefs somehow prescribe the world how to behave. Just compile your program in MSVC Debug mode or with g++ -D_GLIBCXX_DEBUG and witness by your own eyes it is crashing! What else do you want? And this is not a fault of those compilers, the fault is in your code. This is why you need to change your code and not claim that the whole world is wrong and only your ideas are right. |
| Bo Persson <bo@bo-persson.se>: Jun 11 01:27PM +0200 On 2021-06-11 at 13:16, Bonita Montero wrote: > -interface which is specified under the link I've shown you. And > with this there is no opportunity to get the size of the memory > actually allocated. The library implementor knows how std::allocator gets its memory, because he wrote that earlier. So he can predict what the underlying memory manager will actually return when you ask for 7, or 53, bytes. The container can make use of that knowledge, for example by asking the allocator for 64 bytes instead of 53. And now reserve(53) can result in capacity() == 64. |
| MrSpook_0nG@p900whw6_n8r7ovwuul.ac.uk: Jun 11 11:34AM On Fri, 11 Jun 2021 13:22:37 +0200 >objects - i.e. invocation of their constructor via e.g. placement new. >On the contrary, reserve() allocates memory but does /not/ construct the >objects. It is UB to access objects before their construction. POD types do not need to be constructed. As long as the memory is addressable thats all that matters. Why do you think I used ints as an example? |
| MrSpook_35@s879vvmwpgee7rpqv.net: Jun 11 11:38AM On Fri, 11 Jun 2021 14:26:18 +0300 >Just compile your program in MSVC Debug mode or with g++ >-D_GLIBCXX_DEBUG and witness by your own eyes it is crashing! What else >do you want? Thats not a crash, thats a compiler runtime warning. If it accessed OOB memory then the OS would segfault it. >And this is not a fault of those compilers, the fault is in your code. >This is why you need to change your code and not claim that the whole >world is wrong and only your ideas are right. Absolutely none of you seem to understand the what reserve() is doing. Reserve() for vector<int> v is equivalent to: int v[10000]; Resize() would be: int v[10000]; bzero(v,sizeof(v)); Either way you can access the memory up to the array size except in the first case the value is undefined. |
| MrSpook_4421gcxq@fceufv2.ac.uk: Jun 11 11:39AM On Fri, 11 Jun 2021 12:25:20 +0200 >Then there is, of course, ZZ Top's "Woke up with wood", which makes it >rather explicit what it's all about. >Except, I don't understand why Amii Stewart was /knocking/ on it. Knocking on wood is superstitious drivel in the english speaking world. You do it to ward off bad luck. |
| David Brown <david.brown@hesbynett.no>: Jun 11 01:45PM +0200 On 11/06/2021 13:17, Bonita Montero wrote: >> the standard library - they are not restricted to the public API. ... > They are because they're restricted to the specified behaviour of the > allocator template-parameter. No, they are not. They need to be able to work with allocators that provide nothing beyond the specified API. But that does not mean that they can use more information and more methods when dealing with standard library allocators. (You snipped my other points - is that because you don't understand them, or because you know they show you are wrong but won't admit it?) |
| Bonita Montero <Bonita.Montero@gmail.com>: Jun 11 01:53PM +0200 > The library implementor knows how std::allocator gets its memory, > because he wrote that earlier. The allocator template-parameter is replaceable, so the code calling it has to adhere to its interface. So there's no opportunity to get the size actually physically allocated. |
| Bonita Montero <Bonita.Montero@gmail.com>: Jun 11 01:54PM +0200 > They need to be able to work with allocators that provide nothing beyond > the specified API. But that does not mean that they can use more > information and more methods when dealing with standard library allocators. The allocator template-parameter is replaceable, so the code has to content itself with the API a allocator provides. |
| Manfred <noname@add.invalid>: Jun 11 02:14PM +0200 >> objects. It is UB to access objects before their construction. > POD types do not need to be constructed. As long as the memory is addressable > thats all that matters. Why do you think I used ints as an example? You also asked why there is a need for both reserve() and resize(), which is another formulation of the same question. I gave the answer and the rationale for it. If you want to try and find an exception for a special case of some specifically qualified clause of some sort (and if you are willing to bet your job on it), go ahead and have fun diving into the 1800+ pages of legalese of the standard. A word of advise: a quick look at [intro.object] shows: 1. An object is created by a definition (6.2), by a new-expression (7.6.2.7), by an operation that implicitly creates objects (see below), when implicitly changing the active member of a union (11.5), or when a temporary object is created (7.3.4, 6.7.7) Now you may want to look into "implicitly created objects": 13. "[Note: Some functions in the C++ standard library implicitly create objects (20.10.9.2, 20.10.12, 21.5.3, 26.5.3). —end note]" Then you are referenced a.o. to 20.10.9.2 [allocator.traits.members] [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n); 1. Returns: a.allocate(n). Which redirects you to Allocator::allocate; for the default allocator you have [allocator.members]: [[nodiscard]] constexpr T* allocate(size_t n); 2 Mandates: T is not an incomplete type (6.8). 3 Returns: A pointer to the initial element of an array of n T. 4 Remarks: The storage for the array is obtained by calling ::operator new (17.6.2), but it is unspecified when or how often this function is called. This function starts the lifetime of the array object, but not that of any of the array elements. Note the last sentence: "This function starts the lifetime of the array object, but not that of any of the array elements" Obviously it's perfectly possible that that's not the end of it. Have fun! |
| Paavo Helde <myfirstname@osa.pri.ee>: Jun 11 03:14PM +0300 >> do you want? > Thats not a crash, thats a compiler runtime warning. If it accessed OOB memory > then the OS would segfault it. Explain that to the customer who is complaining that your program crashes when she compiles it with a mainstream compiler with her favorite settings. |
| MrSpook_p_5Ko4g@21yhpi_n4fck_wfz.org: Jun 11 12:50PM On Fri, 11 Jun 2021 14:14:53 +0200 >> POD types do not need to be constructed. As long as the memory is addressable >> thats all that matters. Why do you think I used ints as an example? >You also asked why there is a need for both reserve() and resize(), And I haven't had a proper answer yet. I see zero reason for reserve() existing. >If you want to try and find an exception for a special case of some >specifically qualified clause of some sort (and if you are willing to I was making a point about reserve() allocating memory, nothing more. >bet your job on it), go ahead and have fun diving into the 1800+ pages >of legalese of the standard. I'll leave that to the aspies. tl;dr |
| MrSpook_uQjuVe@5szcyauh_pjzi228wvwn.info: Jun 11 12:52PM On Fri, 11 Jun 2021 15:14:57 +0300 >Explain that to the customer who is complaining that your program >crashes when she compiles it with a mainstream compiler with her >favorite settings. More likely his unless you live in a parallel woke universe. I'm simply pointing out that reserve() reserves memory that allows PODs to be used which leads on to my point as to whats the point of it when resize() should always be used. |
| Paavo Helde <myfirstname@osa.pri.ee>: Jun 11 04:37PM +0300 >> crashes when she compiles it with a mainstream compiler with her >> favorite settings. > More likely his unless you live in a parallel woke universe. Obviously you missed the point why I used "her" here :-) I conclude you are living alone. > pointing out that reserve() reserves memory that allows PODs to be used > which leads on to my point as to whats the point of it when resize() should > always be used. Reserve() is an optimization feature which can increase the speed and reduce the memory usage of the program when used properly. As such, it is not necessary to use it, as these potential performance improvements are modest and do not make big-O difference. However, reserve() might also be necessary in the case when the objects placed in the container cannot have working copy or move constructors, or they are extremely expensive. If you have reserved enough memory in the vector, then emplace_back() et al are guaranteed to not reallocate the buffer, so no copy or move constructor is called. Now one could argue that it would be almost always possible to provide a cheap move constructor, and therefore there is no inherent need for reserve(). There might be some truth in it, but the thing is that we didn't have move constructors before 2011, and vector::reserve() was there beforehand, as a way to partially compensate for this lack. |
| David Brown <david.brown@hesbynett.no>: Jun 11 03:58PM +0200 On 11/06/2021 13:54, Bonita Montero wrote: >> allocators. > The allocator template-parameter is replaceable, so the code has to > content itself with the API a allocator provides. Sometimes this is like talking to a brick wall. You are so convinced that you know /everything/ that you won't try to read, and you certainly won't try to /think/. You asked a question in this thread. I gave you the answer. You reject that because of your incorrect preconceptions. You can go back to being ignorant - I'm done trying to help. If you decide to read what other people post and perhaps even rub a couple of brain cells together to understand the help you are given, let us know. Oh, and /please/ do us the courtesy of learning how to quote properly with attributions. |
| Bonita Montero <Bonita.Montero@gmail.com>: Jun 11 04:35PM +0200 You say: > undocumented features that allow std::vector to see how much > memory it has /actually/ een allocated, and let it set "capacity" > a little higher. And this can't be true since the container-implementation has to stick with what an allocator provides. Otherwise it wouldn't be replaceable. |
| MrSpook_9fpRQm@i1z834r.net: Jun 11 02:58PM On Fri, 11 Jun 2021 16:37:36 +0300 >> More likely his unless you live in a parallel woke universe. >Obviously you missed the point why I used "her" here :-) I conclude you >are living alone. Obviously I did. And you're wrong. >However, reserve() might also be necessary in the case when the objects >placed in the container cannot have working copy or move constructors, OK, that is a good reason for it. |
| Manfred <noname@add.invalid>: Jun 11 05:06PM +0200 On 6/11/2021 3:37 PM, Paavo Helde wrote: >> On Fri, 11 Jun 2021 15:14:57 +0300 >> Paavo Helde <myfirstname@osa.pri.ee> wrote: >>> 11.06.2021 14:38 MrSpook_35@s879vvmwpgee7rpqv.net kirjutas: [...] > reserve(). There might be some truth in it, but the thing is that we > didn't have move constructors before 2011, and vector::reserve() was > there beforehand, as a way to partially compensate for this lack. but emplace_back was first standardized in 2011 too, which would make it hard to construct an object in-place before then anyway. The argument is still valid though. |
| Paavo Helde <myfirstname@osa.pri.ee>: Jun 11 02:03PM +0300 11.06.2021 04:31 Lynn McGuire kirjutas: > I want multiple threads to share the massive dataset that we use. Very > tricky, I have tried sharing data between the threads and it was a > disaster. MFC is not thread-safe, so only the main thread can call any MFC functions. For data exchange the most robust way is to use a couple of message queues for passing events back and forth between the threads. Any data which is not MT-safe to access should be copied by value into a new non-shared object when putting into the queue. One can easily build such a queue with a std::queue and a std::mutex. For example, if a background queue wants to display a message to the user, it can send an event to the main thread queue containing the message. The main thread would check in a MFC OnIdle() function if there are any events in the queue, and process them in the main thread. |
| Paavo Helde <myfirstname@osa.pri.ee>: Jun 11 03:19PM +0300 11.06.2021 14:03 Paavo Helde kirjutas: > which is not MT-safe to access should be copied by value into a new > non-shared object when putting into the queue. > One can easily build such a queue with a std::queue and a std::mutex. s/std::queue/std::deque/ |
| Manfred <noname@add.invalid>: Jun 11 01:37PM +0200 On 6/11/2021 12:17 AM, Öö Tiib wrote: > by local legislature. So it is symbolic for me and attempts to censor > it are also symbolic for me and discussing it is not Real Troll's fault > but mine. As far as I am concerned, I don't think there was any fault. c.l.c and c.l.c++ are about the languages, so their topicality is clear, but they are also part of Usenet, for which freedom (with no compromises, as the Internet was originally thought of when it was made public) is a distinctive character. So, up to some extent, the occasional comment about free speech and concern for censorship (which I agree is becoming more and more a real issue) is still appropriate. Thanks for sharing. |
| You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment