Jump to content

  • Log In with Google      Sign In   
  • Create Account

m3mb3rsh1p

Member Since 27 Mar 2008
Online Last Active Today, 06:21 PM

#5285813 Why is my struct destructor not called?

Posted by m3mb3rsh1p on 08 April 2016 - 09:24 AM

@Bitmaster...

 

I said pointers must be used because they are the language facility for managing object... "lifetime," for lack of a better word. Sorry you caught my post before I edited it to reflect my concerns about turning to "advanced concepts" not placement new specifically. The OP asked "Why am I not getting Destruct A [500]?!." The answer, in my opinion should have been something like "Because you need to call "delete a" on a A* or exit the scope which does not automatically happen when you assign." The assignment was addressed early but I reproach the jump to topics about optimization, stack, free-store, dynamic allocation, placement new all to avoid the most basic of C++ concepts: pointers and new+delete.

 

A user-defined type need not allocate any memory to have a non-trivial destructor but the "basic" way of taking control of an object's lifetime away from the automatic scoping is to use a pointer. Surely it is folly to be suggesting that pointers+new+delete = dynamic allocation = free store = slow = much typing = avoid, avoid, avoid?? The OP wanted to dynamically destroy (ie before end of scope)  why are we trying to concoct a static allocation??

 

The OP clearly hit a gotcha in expecting the destructor to be called within the scope of the function. Pointers are necessary, irrespective of the language facility, allocator, container or custom class used to implement RAII / reduce typing / avoid arrow dereferencing / avoid free-store...etc. C/C++ programmers MUST know that they are responsible for their object's lifetime from the moment they declare a variable. This is the C/C++ way.

 

Automatic initialization+destruction and support structures exist to allow the programmer to delegate that responsibility not be relieved of it. "Thou shalt assume responsibility for this object's lifetime, on my behalf, from point A (e.g initialization) to point B(e.g end of scope or reset()). Placement new, manual destructor call, and all the other expert "implementations" of handling object lifetime must not change "Good Practice" in using variables/pointers/objects/references especially in main() or any other user-level function.

 

My example was meant to demonstrate the awareness a programmer should have of object lifetime, with particular respect to end of scope which is why I showed the unique_ptr example as one way of delegating responsibility and avoiding manual new+delete. "...an emphatic no." to the use of free store is a bit extreme. If one prefers to dabble in stack-only allocation then they are free to place "new" there, even for unique_ptr.

 

It is certainly interesting to explore the advanced concepts related to object allocation but all that "expert" knowledge belongs in "encapsulation." "General Programming" should be a place to exemplify good coding practices, moreso than "For Beginners" IMO. Bjarne Stroustrup and most of the "top brass" regularly bemoan the tendency of experts to turn basic questions into in-depth analyses of advanced language concepts instead of demonstrating the virtues and wonders of simplicity.

 

"The Pointer" is basic C/C++. It is what clearly defines the languages from Java, C# and others. The years have afforded us facilities to delegate object lifetime management but it remains our greatest advantage that we can say and aspire to guarantee that a particular scope behaves as it appears (as long as we don't go fighting the language with "expert" tricks).




#5285781 Why is my struct destructor not called?

Posted by m3mb3rsh1p on 08 April 2016 - 06:37 AM

Hmm, the replies seemed to jump straight to advanced concepts, skipping the basic new + delete which is how C++ works at the basic level:

    A *a = new A;
    a->val = 500;

    delete a;
    a = new A();
    printf( "Finally %d\n", a->val );
    a->val = 300;

    delete a;
    return 0;

The recommended practice these days is to use the standard library, but the point to remember is that pointers MUST be used if object destruction is needed before exiting scope.
 

#include <memory>

struct A { int val; };

int main()
{
    std::unique_ptr a{ new A};
    a->val = 500;

    a.reset(new A);
    printf("Finally %d\n" a->val);
    a->val = 300;
}

I believe manual scoping might work as well in some case but here, it seems you need "a" for the entire scope...

int main()
{
    A a;
    a.val = 500;
 
    {
        A b;
        b.val = 300;
        a.val = b.val;
        printf("Destroying b...\n");
    }
}



#4989608 Virtual Coin Flip

Posted by m3mb3rsh1p on 12 October 2012 - 05:28 PM

Hi. I'm also a beginner so I thought I'd share my solution. I'm stuck at how to count the flips without loops because I don't quite yet have a firm grasp of the Java utils.

I enjoyed this. Thanks to all!
import java.util.Random;
import java.util.Arrays;
import java.util.Collections;

public class Coin
{
public enum Side { heads, tails, edge };

public Coin()
{
	_side = Side.edge;
}
public Coin(Side side)
{
	_side = side;
}
public Coin(Random generator)
{
	flip(generator);
}
public void flip(Random generator)
{
	double value = generator.nextDouble();

	if(value < 0.5 )
	{_side = Side.heads;}
	else if(value > 0.5)
	{_side = Side.tails;}
	else
	{_side = Side.edge;}
}
public boolean equals(Coin other)
{
	return _side == other._side;
}
public String toString()
{
	return _side.toString();
}
	private Side _side;

public static void main(String[] args)
{
	Coin heads = new Coin(Side.heads);
	Coin tails = new Coin(Side.tails);
	
	Random rand = new Random();
	
	Coin[] coins = new Coin[]
	{
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand),
		new Coin(rand)
	};

	System.out.println(Arrays.toString(coins));

	int numHeads = Collections.frequency(Arrays.asList(coins), heads);
	System.out.println("There are " + numHeads + " heads.");

	int numTails = Collections.frequency(Arrays.asList(coins), tails);
	System.out.println("There are " + numTails + " tails.");
}
}

I encountered some challenges while finding the "right way"
- no easy way to "apply"
- countif/equality not working here
- *()&(SFHKJHSF(&(*&:>( code tags!!


#4913896 How a derived class cannot resolved members of its base class at compile time?

Posted by m3mb3rsh1p on 17 February 2012 - 07:28 AM

With all due respect, Washu, turning the question into an analysis of assembly language doesn't help make it easier to understand. If the concepts are straightforward to you, please simplify them for us.


PARTNERS