- Happy Thanksgiving - 1 Update
- What happens to unique_ptr -pointer in this case - 16 Updates
- Questions about custom allocator - 2 Updates
- Custom Memory Manager & placement new - 3 Updates
- a problem about programming - 3 Updates
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Nov 24 04:56AM -0800 Psalm 100 http://biblehub.com/kjv/psalms/100.htm Shout for Joy to the Lord, All You Lands! 1 {A Psalm of praise.} Make a joyful noise unto the LORD, all ye lands. 2 Serve the LORD with gladness: come before his presence with singing. 3 Know ye that the LORD he is God: it is he that hath made us, and not we ourselves; we are his people, and the sheep of his pasture. 4 Enter into his gates with thanksgiving, and into his courts with praise: be thankful unto him, and bless his name. 5 For the LORD is good; his mercy is everlasting; and his truth endureth to all generations. ----- There is love, peace, and joy in the house of the Lord, but only when you keep your eyes focused on Him. If you begin looking around at the things of the world, they will quickly pull you under. But when you look up to Him, and keep looking up, there you find your peace, because only there is your salvation. Remember also ... Peter walked on water too, but only when he was looking at the Lord! http://biblehub.com/kjv/matthew/14.htm 28 And Peter answered him and said, Lord, if it be thou, bid me come unto thee on the water. 29 And he said, Come. And when Peter was come down out of the ship, he walked on the water, to go to Jesus. 30 But when he saw the wind boisterous, he was afraid; and beginning to sink, he cried, saying, Lord, save me. 31 And immediately Jesus stretched forth his hand, and caught him, and said unto him, O thou of little faith, wherefore didst thou doubt? 32 And when they were come into the ship, the wind ceased. 33 Then they that were in the ship came and worshipped him, saying, Of a truth thou art the Son of God. Jesus will save your eternal soul, and give you eternal life. All you have to do is trust and believe. Best regards, Rick C. Hodgin |
JiiPee <no@notvalid.com>: Nov 24 12:36AM Just cannot be sure what happens if I do the following: class A { public: void foo() { delete this; } }; int main() { std::unique_ptr<A> b; b.foo(); // (*) here: what is the state of b? } How does b know that its object is deleted? Can i use b normally after (*) or is it in undefined state? If I want to delete the object inside foo(), how should i do it so that b is in good state, or is it even possible? Is this a wrong way to use unique_ptr (so we should not delete object inside its member variable)? |
JiiPee <no@notvalid.com>: Nov 24 12:42AM Sorry, should be like this in main: std::unique_ptr<A> b = std::make_unique<A>(); b->foo(); On 24/11/2016 00:36, JiiPee wrote: |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 24 12:56AM On Thu, 24 Nov 2016 00:36:37 +0000 > that b is in good state, or is it even possible? > Is this a wrong way to use unique_ptr (so we should not delete object > inside its member variable)? b.foo() won't compile, and presumably you meant b->foo(). If so, yes, you have it completely wrong. First you have not actually allocated an A object, so b->foo will dereference a null pointer and the program will terminate. Secondly even if you had allocated an A object to be managed by b, your code would cause a double delete, memory corruption and woe, because b->foo() would delete the A object, and b would try to do the same when it goes out of scope. You need to look up some documentation on unique_ptr. They are very simple things - it should take you about 10 minutes to work it out. You could do what you want by releasing the unique_ptr when you call A::foo() (see std::unique_ptr::release()), but having an object know what object manages it defeats the purpose of using unique_ptr in the first place. Just leave it to the unique_ptr to deal with deallocation, or adopt a different design. |
JiiPee <no@notvalid.com>: Nov 24 01:19AM On 24/11/2016 00:56, Chris Vine wrote: > memory corruption > and woe, because b->foo() would delete the A object, and b would try > to do the same when it goes out of scope. Thats what I also thought. The reason I ask this is becouse with Microsoft MFC its quite common practice for people to do: delete this; When the window-objects window gets destroyed: void CMyDialog::OnNcDestroy() { CDialog::OnNcDestroy(); delete this; } So, is this a wrong approach? Many do this though....and I think also MFC does that something inside the library? (In this example we know that CMyDialog is created dynamically with new) |
JiiPee <no@notvalid.com>: Nov 24 01:20AM On 24/11/2016 00:56, Chris Vine wrote: > you have it completely wrong. First you have not actually allocated > an A object, so b->foo will dereference a null pointer and the program > will terminate. Yes, there was a mistake.. see my other post |
JiiPee <no@notvalid.com>: Nov 24 01:26AM On 24/11/2016 00:56, Chris Vine wrote: > Just leave it to the unique_ptr to deal with > deallocation, or adopt a different design. So this means that "delete this;" is not a good practise, right? Because it might lead to confusion. |
Jerry Stuckle <jstucklex@attglobal.net>: Nov 23 10:57PM -0500 On 11/23/2016 8:19 PM, JiiPee wrote: > So, is this a wrong approach? Many do this though....and I think also > MFC does that something inside the library? > (In this example we know that CMyDialog is created dynamically with new) But MFC doesn't use unique_ptr, so someone has to delete it or you have a memory leak. And after the return from OnNcDestroy() the object should never be referenced again (and isn't in MFC). -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Jerry Stuckle <jstucklex@attglobal.net>: Nov 23 10:57PM -0500 On 11/23/2016 8:26 PM, JiiPee wrote: >> deallocation, or adopt a different design. > So this means that "delete this;" is not a good practise, right? Because > it might lead to confusion. It all depends on the circumstances. If you do use it, ensure to document it. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 24 05:45AM +0100 On 24.11.2016 01:42, JiiPee wrote: >> b.foo(); >> // (*) here: what is the state of b? >> } When `std::unique_ptr` destructor attempts to destroy the object it's already destroyed, and you have Undefined Behavior. The proper way for the object to self-destruct is to do that via the single owner, here the smart pointer. Which means the object needs knowledge of its owner, or be provided with a self-destruct operation that does. Cheers & hth., - Alf |
Paavo Helde <myfirstname@osa.pri.ee>: Nov 24 09:18AM +0200 On 24.11.2016 3:19, JiiPee wrote: > { > CDialog::OnNcDestroy(); > delete this; After this, there must not be another delete called for this object. This means that either the object was not managed by smart pointers at all, or that OnNcDestroy() was called from the destructor of the last smart pointer. In case of MFC it is the former, the objects are managed by raw pointers by using strict ownership conventions. This is possible because MFC is single-threaded. Cheers Paavo |
Paavo Helde <myfirstname@osa.pri.ee>: Nov 24 09:31AM +0200 On 24.11.2016 3:26, JiiPee wrote: >> deallocation, or adopt a different design. > So this means that "delete this;" is not a good practise, right? Because > it might lead to confusion. 'Delete this;' is rarely a good practice. Since C++11 one has several standardized smartpointers which should be used instead. In general, a naked 'delete' should not appear in application level code at all. If not for other reasons, then just because it is inherently exception-unsafe. With legacy frameworks like MFC one needs to use their conventions of course, and if this requires writing 'delete this;' then so be it. Cheers Paavo |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 24 10:08AM On Thu, 24 Nov 2016 01:26:26 +0000 > > deallocation, or adopt a different design. > So this means that "delete this;" is not a good practise, right? > Because it might lead to confusion. 'delete this' is OK in cases where an object is entirely self-owning. Non-modal GUI dialogs in an asynchronous event loop are one of the few examples - their lifetime is ended by the program user clicking on a close button or the like (which are events which the object itself receives and handles in many GUI systems), and bears no relation to anything else in the program (apart from program termination). If the dialog receives the click notification, it might as well kill itself with 'delete this' rather than delegate that to some firing squad it specially sets up for the purpose. You have to obey the usual conventions - once 'delete this' has been called, no non-static member data of the object may be accessed and no non-static methods of the object may be called. The only thing the method can sensibly do is return, which yours did. I have code which does that with no embarassment. It's all a question of clear ownership. If you use a unique_ptr to manage an object allocated on free store, you are declaring that the unique_ptr (or some other one to which it is moved) is responsible for managing lifetime. In that case you should let the unique_ptr do its thing. For most usages unique_ptr is ideal. If you need shared ownership then use shared_ptr. Only in the case of self-ownership (usually, as I say, in event driven programming) should you consider 'delete this'. Chris |
"Öö Tiib" <ootiib@hot.ee>: Nov 24 04:03AM -0800 On Thursday, 24 November 2016 09:31:45 UTC+2, Paavo Helde wrote: > In general, a naked 'delete' should not appear in application level code > at all. If not for other reasons, then just because it is inherently > exception-unsafe. Interesting fact that one usage of 'delete this' that I have seen was for to achieve strong exception safety (erase-commit/rollback). |
JiiPee <no@notvalid.com>: Nov 24 12:35PM On 24/11/2016 03:57, Jerry Stuckle wrote: > But MFC doesn't use unique_ptr, so someone has to delete it or you have > a memory leak. And after the return from OnNcDestroy() the object > should never be referenced again (and isn't in MFC). but even if it is not a smart pointer, the user must still *know* that the function will destroy it. Is there a risk here and confusion that if the user forgots that its self deleted? How does the user remember that in this occasion the object will be self-destroyed? |
JiiPee <no@notvalid.com>: Nov 24 12:37PM On 24/11/2016 07:31, Paavo Helde wrote: > With legacy frameworks like MFC one needs to use their conventions of > course, and if this requires writing 'delete this;' then so be it. You would not mix the modern C++ with MFC? |
JiiPee <no@notvalid.com>: Nov 24 12:42PM Ok, this was pretty clear explanation. So in this occasion its ok because MFC uses that convention. On 24/11/2016 10:08, Chris Vine wrote: |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Nov 24 06:09AM -0600 I found this article: http://www.drdobbs.com/the-standard-librarian-what-are-allocato/184403759 Although it predates C++11, I can't find anything more recent, so here I am playing with the code and trying to understand it. I get the following output from my code (listed below): Allocated 16 bytes for a struct std::_Container_proxy Complex Number constructed Allocated 24 bytes for a class ComplexNumber Complex Number copy constructed Complex Number deconstructed Complex Number deconstructed Deallocated 24 bytes for a class ComplexNumber Deallocated 16 bytes for a struct std::_Container_proxy Why are 16 bytes allocated before space for the actual data I am putting into the std::vector and what is a container_proxy? When 'placement new' is called, is that when the object is being copy constructed? and if I understand right, copy constructed into the memory I allocated? What is the second argument in pointer allocate(size_type n, const_pointer = 0) ? What is the second argument in void deallocate(pointer p, size_type) ? This makes no sense to me. What is the max size supposed to be and why is it a negative number? Or is this some unsigned/signed trickery? size_type max_size() const { return static_cast<size_type>(-1) / sizeof(value_type); } Here is my listing: // Standard Includes #include <iostream> //------------------------------------------------------------------------------ /// <summary> /// A STL compliant custom allocator /// After C++11 this changes a bit by dropping much boiler plate code /// /// Based on Dr Dobbs article /// http://www.drdobbs.com/the-standard-librarian-what-are-allocato/184403759 /// </summary> template <class T> class malloc_allocator { public: typedef T value_type; typedef value_type * pointer; typedef const value_type * const_pointer; typedef value_type & reference; typedef const value_type & const_reference; typedef std::size_t size_type; // typedef std::ptrdiff_t difference_type; // Gives compile error malloc_allocator() { // Allocators before C++11 are expected to be stateless } malloc_allocator(const malloc_allocator & rhs) { } ~malloc_allocator() { } void operator =(const malloc_allocator & rhs) = delete; bool operator == (const malloc_allocator<T> & rhs) { return true; } bool operator != (const malloc_allocator<T> & rhs) { return false; } template <class U> malloc_allocator(const malloc_allocator<U> &) { } template <class U> struct rebind { typedef malloc_allocator<U> other; }; pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } pointer allocate(size_type n, const_pointer = 0) { const size_type numBytes = n * sizeof(T); void * p = std::malloc(numBytes); if (!p) { throw std::bad_alloc(); } std::cout << "Allocated " << numBytes << " bytes for a " << typeid(T).name() << std::endl; return static_cast<pointer>(p); } void deallocate(pointer p, size_type) { const size_type numBytes = sizeof(*p); std::free(p); std::cout << "Deallocated " << numBytes << " bytes for a " << typeid(T).name() << std::endl; } size_type max_size() const { return static_cast<size_type>(-1) / sizeof(value_type); } void construct(pointer p, const value_type & x) { // 'Placement new' constructs an object at a specified location // The custom allocator seperates allocation from construction new(p) value_type(x); } void destroy(pointer p) { p->~value_type(); } }; // Template specialization for void type // Our custom allocator does not work when a container refers to void pointers. // We refer to sizeof(T) and T& which is not legal when T is void. // Therefore we must specialize. // Leaves out everything except what is needed for referring to void pointers template<> class malloc_allocator<void> { typedef void value_type; typedef void * pointer; typedef const void * const_pointer; template <class U> struct rebind { typedef malloc_allocator<U> other; }; }; //------------------------------------------------------------------------------ class ComplexNumber { public: ComplexNumber(double realPart, double complexPart); ComplexNumber(const ComplexNumber & rhs); virtual ~ComplexNumber(); protected: double m_realPart; double m_complexPart; }; //------------------------------------------------------------------------------ ComplexNumber::ComplexNumber(double realPart, double complexPart) : m_realPart(realPart) , m_complexPart(complexPart) { std::cout << "Complex Number constructed" << std::endl; } //------------------------------------------------------------------------------ ComplexNumber::ComplexNumber(const ComplexNumber & rhs) : m_realPart(rhs.m_realPart) , m_complexPart(rhs.m_complexPart) { std::cout << "Complex Number copy constructed" << std::endl; } //------------------------------------------------------------------------------ ComplexNumber::~ComplexNumber() { std::cout << "Complex Number deconstructed" << std::endl; } //------------------------------------------------------------------------------ void RunCustomAllocator() { std::vector<ComplexNumber, malloc_allocator<ComplexNumber> > myVector; ComplexNumber number(1, 1); myVector.push_back(number); } //------------------------------------------------------------------------------ int main(int argc, char * argv[]) { // RunNoMemoryManagement(); // RunSimpleMemoryManagement(); RunCustomAllocator(); return 0; } |
mark <mark@invalid.invalid>: Nov 24 01:38PM +0100 On 2016-11-24 13:09, Christopher J. Pisz wrote: > Deallocated 16 bytes for a struct std::_Container_proxy > Why are 16 bytes allocated before space for the actual data I am putting > into the std::vector and what is a container_proxy? Probably iterator tracking / debugging: <https://hadibrais.wordpress.com/2013/11/13/dissecting-the-c-stl-vector-part-2-constructors/> > What is the second argument in pointer allocate(size_type n, > const_pointer = 0) ? > What is the second argument in void deallocate(pointer p, size_type) ? http://en.cppreference.com/w/cpp/memory/allocator > { > return static_cast<size_type>(-1) / sizeof(value_type); > } For unsigned types, -1 is equivalent to numeric_limits<size_type>::max(). |
"Chris M. Thomasson" <invalid@invalid.invalid>: Nov 23 08:20PM -0800 On 11/23/2016 1:24 PM, Chris M. Thomasson wrote: > ________________________________________ > This was back when I was still trying out custom allocation techniques > in C++. I am sad to say that MSVC 2015 has the exact same error for me! I get: _________________________________________ custom_allocator::allocate(00BBD930, 2234) custom_allocator::deallocate(00BBD930, 2234) custom_allocator::allocate(00BC0038, 11170) custom_allocator::deallocate(00BC0038, 2234) _________________________________________ This is very wrong! However, it works online here in a different compiler: http://cpp.sh/94sf7 _________________________________________ custom_allocator::allocate(0x20b0900, 2234) custom_allocator::deallocate(0x20b0900, 2234) custom_allocator::allocate(0x20b0900, 11178) custom_allocator::deallocate(0x20b0900, 11178) _________________________________________ and on GCC. AFAICT, MSVC has a bug here in Version 14.0.25424.00 Update 3 at least... Damn. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 24 10:50AM On Wed, 23 Nov 2016 20:20:00 -0800 > AFAICT, MSVC has a bug here in Version 14.0.25424.00 Update 3 at > least... > Damn. This is a really old bug in delete[] which has been around for ages, and which Microsoft will readily admit to. However they say they can't change it because it would break code which relies on the faulty implementation (not least their own Windows operating system). It has cropped up on this newsgroup a few times before. What the size_t argument is passed in operator delete[] is the element size for the type for which new[] was called, and not the allocated block size. Quite what led them to think that is what the standard requires is beyond me. The first suggested work-around is to have your class specific operator new[] and operator delete[] forward to global operator new[] and global operator delete[] so that your custom allocator only works when allocating individual objects (or to not provide class specific operator new[] and operator delete[] at all, which has the same effect), which is what most people do. If you really need custom allocation for arrays and the object is not std::allocator aware, the other workaround is to use the initial few bytes of any memory allocated with new[] (say, an unsigned int's worth) to the size of the allocation, and to return not the beginning of the memory block allocated, but the address immediately after the int (the start of "object space"). operator delete[] can then read back four bytes and obtain the int value when it comes to delete[] time. |
mark <mark@invalid.invalid>: Nov 24 12:50PM +0100 On 2016-11-24 11:50, Chris Vine wrote: > after the int (the start of "object space"). operator delete[] can then > read back four bytes and obtain the int value when it comes to delete[] > time. How do you read back those 4 bytes without relying on undefined behavior? There are compilers (including GCC) that may mis-compile code like that (it's C, but the restrictions on C++ pointer math should be similar enough): "C memory object and value semantics: the space of de facto and ISO standards" https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf |
Lino <lino@net.com>: Nov 24 12:37AM +0100 Louis Krupp wrote: > Does it work? If so, congratulations! If not, please post your code > and your results. > Louis ------------------------------------------------ code written in AFL language (Amibroker Formula Language) [https://www.amibroker.com/guide/AFL.html] AB = CreateObject("Broker.Application"); sts = AB.Stocks(); Qty = sts.Count; for( i = Qty - 1; i >= 0; i = i - 1 ) { st = sts.Item( i ); Ticker = st.Ticker; printf("changing " + Ticker + "\n" ); Length = StrLen(Ticker ); if( StrFind(Ticker, "TO:") ) st.Ticker= "TC-"+StrRight(Ticker,Lenght+3); } ------------------------------------------------------------- haven't a code result. The result is in the symbol changed on my database on the screen. ...and the results are 2 errors: [1]. change only 1 symbol a time (every time i click "apply") and I think it's a "FOR Cycle" problem. [2]. Example: I have a list symbols on the left side [below] -----> and the result in the symbols modified [every time I click apply script] in the right side. TO:A TC-T:A [wrong] TO:DE TC-:DE [wrong] TO:ASD TC-ASD OK <<<<<<< Thats OK (I want this) TO:AXMA TC-XMA [Wrong] TO:ERJTT TC-JTT [wrong] I want to change in this case "ONLY" the "TO:" [or in other case the part of string that I want to change from the first chacacter on the left] leaving the rest the same as originally printed. |
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Nov 23 07:44PM -0700 > Length = StrLen(Ticker ); > if( StrFind(Ticker, "TO:") ) > st.Ticker= "TC-"+StrRight(Ticker,Lenght+3); What is 'Lenght', and why are you adding 3 to it? Does AFL allow you to use variables you haven't declared? Louis |
Lino <lino@net.com>: Nov 24 09:43AM +0100 Louis Krupp ha usato la sua tastiera per scrivere : > What is 'Lenght', and why are you adding 3 to it? > Does AFL allow you to use variables you haven't declared? > Louis please note that I'm not a programmer. I have only copy an existant code to adapt it for this little work for changing the name ot multiple symbol on Dbase. -I think (but not sure) the plus (on Lenght) isin't necessary on StrRight [https://www.amibroker.com/guide/afl/strright.html] -Lenght is a lenght (number) of the sting of the symbol (StrLeng) http://www.amibroker.com/guide/afl/strlen.html |
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