Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
jonjonaug
Mar 26, 2010

by Lowtax

evensevenone posted:

isn't that going to cause a memory leak though?

new B is going to allocate sizeof(B), but the delete var is going to delete only sizeof(A) since var is an A*.

That isn't how delete works, I think. As long as you delete something the same way you allocated it you should be fine.

Also I did this and had stable memory usage.

code:
while(true)
{
   A* ptr=new B;
   delete ptr;
}

Adbot
ADBOT LOVES YOU

Null Pointer
May 20, 2004

Oh no!
Yeah, virtual destructors are your friends.

evensevenone
May 12, 2001
Glass is a solid.
That's actually really awesome.

UraniumAnchor
May 21, 2006

Not a walrus.
virtual destructors just mean that ~B() gets called instead of ~A(), it will still free sizeof(B) bytes even if you forget to mark it virtual.

http://codepad.org/cXr4TnKo

This does not leak any memory.

Null Pointer
May 20, 2004

Oh no!

UraniumAnchor posted:

This does not leak any memory.
Yes, in the same sense that this:

code:
A* foo = new A[100];
delete foo;
doesn't leak memory.

king_kilr
May 25, 2007

Null Pointer posted:

Yes, in the same sense that this:

code:
A* foo = new A[100];
delete foo;
doesn't leak memory.

Uhh not at all. That trivially leaks memory. delete foo where foo is a B* with a non-virtual destructor only leaks if B has dynamically allocated memory that is expected to be deleted by the destructor

Null Pointer
May 20, 2004

Oh no!

king_kilr posted:

Uhh not at all. That trivially leaks memory.
Guess again.

theg sprank
Feb 3, 2008
pillage your village

Null Pointer posted:

Guess again.

the behavior of the code you posted is undefined soooooo...

Vanadium
Jan 8, 2005

ShoulderDaemon posted:

The size of every allocation as well as destructor information is stored as part of the allocation; the type of a pointer given to delete does not matter, as long as it was allocated with new, it will be correctly deallocated.

Worth pointing out that this only works within a class hierarchy with virtual destructors. :toot:

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Vanadium posted:

Worth pointing out that this only works within a class hierarchy with virtual destructors. :toot:
No, it doesn't. As has already been pointed out several times, virtual/non-virtual destructors have nothing to do with how much memory gets freed (other than that the derived destructor that doesn't get run might have needed to do something).

Vanadium
Jan 8, 2005

Deleting something via a pointer to its baseclass, which does not have a virtual destructor, is undefined behaviour, as is deleting something through a pointer to an entirely different type. :shobon:

Vanadium fucked around with this message at 15:42 on May 8, 2010

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Plorkyeran posted:

No, it doesn't. As has already been pointed out several times, virtual/non-virtual destructors have nothing to do with how much memory gets freed (other than that the derived destructor that doesn't get run might have needed to do something).

No, he's right, part of what I said was that "destructor information is stored as part of the allocation" and that is only true if the destructor is virtual.

functional
Feb 12, 2008

Avenging Dentist posted:

realloc almost always frees/mallocs a new block unless the new block is smaller, and then sometimes it gets optimized for that case.

On OS X realloc reuses the same block for shrinking, and it will grow in an amortized efficient method (ie not n^2). Whether this is a side effect of the set allocation sizes or a property of realloc I don't know, but I was pleasantly surprised to learn about it. Not sure what the behavior is on other systems.

functional fucked around with this message at 01:07 on May 9, 2010

Precambrian Video Games
Aug 19, 2002



I want to make a method that does finite differencing on any kind of member function that returns say a double, like:

code:
double finitedifference(x,y,..., double(*function)(double x, double y, ...))
{
  return function(x-y,x+y,...)/(2*y); // or something more complicated
}
There doesn't seem to be any way to pass a member function with the C++ STL. Specifically, it'll say error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&Class::Function' . I can certainly understand why, and a quick googling suggested there is a magical Boost function that will let me do exactly this, but I'd rather not use it unless I have to. The fact that the STL won't let me do this suggest I shouldn't be doing it in the first place, but I can't think of a more general solution. I suppose I could have every class that needs to do it inherit a virtual function with the same name but that does not seem more elegant or concise.

I also read this which only served to confuse me further. At some point it suggest using a #define macro which sounds like the ugliest hack I could think of. The bit on functionoids sounds more reasonable, but it seems rather pointless given that the most general base class I can think of would be nothing but a bunch of virtual functions.

Precambrian Video Games fucked around with this message at 22:18 on May 8, 2010

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
The STL has nothing to do with it. You can take the address of an instance method; it's just that instance methods are *not* ordinary functions and can't be passed in as one.

The error message suggests that you're also getting the syntax wrong for taking the address of an instance method. It would be helpful to see some code.

Precambrian Video Games
Aug 19, 2002



Well, here's an example that works:

code:
class Function
{
	public:
		double value(double arg) { return 1; };
};

double finitedifference(double arg, double eps, double(Function::*function)(double arg))
{
	Function aFunction;
	return ((aFunction.*function)(arg+eps)+(aFunction.*function)(arg-eps))/(2*eps);
}

int main() {
	cout << finitedifference(0,1,&Function::value) << endl;
	return 0;
}
This is not entirely useless but only saves me the effort of writing another finitedifference method for each method in the Function class. What I want is this:

code:
class Function
{
	public:
		double value(double arg) { return 1; };
};

double finitedifference(double arg, double eps, double(*function)(double arg))
{
	return (function(arg+eps)-function(arg-eps))/(2*eps);
}

int main() {
	cout << finitedifference(0,1,&Function::value) << endl;
	return 0;
}
... which would work on any member function of any class, since I don't really particularly care what it is as long as it returns a double. That compiles if value is static but generally I don't want it to be.

Precambrian Video Games fucked around with this message at 23:21 on May 8, 2010

Mr.Radar
Nov 5, 2005

You guys aren't going to believe this, but that guy is our games teacher.
You could use templates and overloading to do what you want:
code:
template <typename T>
double finiteddifference(double arg, double eps, double(T::*function)(double arg)) 
{
    T funcThis;
    return ((funcThis.*function)(arg+eps)-(funcThis.*function)(arg-eps))/(2*eps);
}

double finiteddifference(double arg, double eps, double(*function)(double arg))
{
	return (function(arg+eps)-function(arg-eps))/(2*eps);
}
You can't escape the need to supply a this value for non-static member functions though.

Mr.Radar fucked around with this message at 23:47 on May 8, 2010

Jose Cuervo
Aug 25, 2004
Can anyone see a glaring error with this code? It runs fine in Microsoft VS 2005 if I hit F5 (debugging), but if I try and run it without debugging mode on (Ctrl+F5) it crashes.

code:
int main ()
{
	int numRuns= 375;  
	int maxAllocs= 1;  
	int numReps= 15; 

	char *results = "newResults.txt";  // Name of results file
	fstream readInStream;
	readInStream.open(results, ios::in);	

	long int* *dataVals= new long int*[numRuns+1];
	long int aNum;
	readInStream>> aNum;  // read in the first -1
	
	int runIdx= 1;
	dataVals[runIdx]= new long int[(maxAllocs*2)+2];
	for (int i=1; i<=(maxAllocs*2)+1; i++)
		dataVals[runIdx][i]= -1999;

	int counter= 1;
	while (!readInStream.eof())
	{	readInStream>> aNum;

		if (aNum == -1)
		{	dataVals[runIdx][counter-1]= -1999;
			counter= 1;
			
			runIdx++;	
			dataVals[runIdx]= new long int[(maxAllocs*2)+2];
			for (int i=1; i<=(maxAllocs*2)+1; i++)
			{	dataVals[runIdx][i]= -1999;
			}
		}
		else
		{	dataVals[runIdx][counter]= aNum;
			counter++;
		}	
	}	
	dataVals[runIdx][counter-1]= -1999;
	readInStream.close();

        return 0;
}
If it helps, my results.txt file is formatted as follows;
code:
-1 45 45 56 67 59
-1 356 389 3
-1 43 476 3

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Oh my god I didn't think anyone actually used Horstmann style braces.

Also you're indexing off the end of your array when you read from the first line.

Jose Cuervo
Aug 25, 2004

Avenging Dentist posted:

Oh my god I didn't think anyone actually used Horstmann style braces.

Also you're indexing off the end of your array when you read from the first line.

Gah, I forgot to change maxAllocs to 2 in the code I posted. It still crashes with maxAllocs= 2.

Is there something wrong with the braces I use?

Jose Cuervo fucked around with this message at 02:31 on May 10, 2010

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
It is the worst brace style I've ever seen (except for "random"). Also your program doesn't crash.

Jose Cuervo
Aug 25, 2004

Avenging Dentist posted:

It is the worst brace style I've ever seen (except for "random"). Also your program doesn't crash.

I have another fstream object(?) declared to write some data to a file. It seems this is the problem. Am I not allowed to have two fstream objects in the same file?
The additional code is:
code:
	fstream writeStream;
	writeStream.open(formatted, ios::out);

	for (int i=1; i<=int(numRuns/numReps); i++)
	{	
		for (int j=1; j<=allocNum; j++)
			writeStream<< averages[j][i] << "  ";

		writeStream<< endl;
	}
	writeStream.close();

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Provide a test case with a reproducible error. I can't track down errors that don't exist.

Jose Cuervo
Aug 25, 2004

Avenging Dentist posted:

Provide a test case with a reproducible error. I can't track down errors that don't exist.

My full code is here.

The text file is called newresults.txt and contains the data found here.

This makes the program crash if I hit Crtl+F5 but not if I only hit F5.

Thank you for your help.

Zakalwe
May 12, 2002

Wanted For:
  • Terrorism
  • Kidnapping
  • Poor Taste
  • Unlawful Carnal Gopher Knowledge

Avenging Dentist posted:

It is the worst brace style I've ever seen (except for "random"). Also your program doesn't crash.


Worse than Whitesmiths and GNU? Surely you jest.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Jose Cuervo posted:

My full code is here.

The text file is called newresults.txt and contains the data found here.

This makes the program crash if I hit Crtl+F5 but not if I only hit F5.

Thank you for your help.

You're still writing off the end of the array.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

Zakalwe posted:

Worse than Whitesmiths and GNU? Surely you jest.

Horstmann is like cancer. It's like someone set out to undermine every editor's auto-indentation mechanism.

OddObserver
Apr 3, 2009

Zakalwe posted:

Worse than Whitesmiths and GNU? Surely you jest.

I don't think any of those styles introduce a risk of the code reader entirely missing a line of code at the beginning of the block...

Jose Cuervo
Aug 25, 2004

OddObserver posted:

I don't think any of those styles introduce a risk of the code reader entirely missing a line of code at the beginning of the block...

Can someone explain what is so terrible about the way I have my braces set up? I am not sure how a reader can miss an entire line of code at the beginning of a block. I have not had a formal computer science class, so the way I set up my braces is the way that made the most sense to me. The code I write is generally not read by others unless I am posting for help (which I seem to do quite a lot these days).

EDIT: Jeez... seems to be quite a lot of different formatting styles on wikipedia.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Basically the whole world (excluding GNU people who are insane anyway) uses K&R or Allman. Horstmann and a its derivatives are the only ones out there that have arbitrary statements on the same line as a brace. All other styles keep braces either 1) on their own line, or 2) on the line of a statement that precedes/follows a block.

Jose Cuervo
Aug 25, 2004

Avenging Dentist posted:

Basically the whole world (excluding GNU people who are insane anyway) uses K&R or Allman. Horstmann and a its derivatives are the only ones out there that have arbitrary statements on the same line as a brace. All other styles keep braces either 1) on their own line, or 2) on the line of a statement that precedes/follows a block.

Okay. If that is the convention then I will switch to that. Thanks for the help (you were right about me writing off the end of my array), and the useful knowledge about indenting.

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender
It's worth noting that even Horstmann stopped using Horstmann style in favor of Allman style.

And on a completely unrelated but similarly so-weird-it's-harmful nature, you really shouldn't pretend your array indexes start at 1 instead of 0.

Both of these things are really needlessly confusing for anyone you want to show your code to, even if they don't seem to cause you personally any problems.

mr_jim
Oct 30, 2006

OUT OF THE DARK

Jose Cuervo posted:

Can someone explain what is so terrible about the way I have my braces set up? I am not sure how a reader can miss an entire line of code at the beginning of a block. I have not had a formal computer science class, so the way I set up my braces is the way that made the most sense to me. The code I write is generally not read by others unless I am posting for help (which I seem to do quite a lot these days).

EDIT: Jeez... seems to be quite a lot of different formatting styles on wikipedia.

There was a long argument about brace styles in the Coding Horrors thread recently. I think your style is the only one that wasn't at least mentioned. Most people seem to use either K&R or Allman, except one guy who apparently still uses Whitesmiths.

The only thing everyone agreed on is that GNU style is poo poo.

Jose Cuervo
Aug 25, 2004

ShoulderDaemon posted:

And on a completely unrelated but similarly so-weird-it's-harmful nature, you really shouldn't pretend your array indexes start at 1 instead of 0.

It causes me problems as well, so it is something else I am going to try and eliminate from my coding. I am used to coding in Matlab where the indices start at 1, but from now on I can only see myself using C++ so I should used the indices correctly.

tractor fanatic
Sep 9, 2005

Pillbug
Is there a way I can resize a vector without reducing its capacity?

If I have an int vector

std::vector<int> my_vector;

and I want to reserve 100 spots, but only want the size of the vector to be 25 for now, won't doing

my_vector.reserve(100);
my_vector.resize(25);

reduce the vector capacity to 25?

I could reserve the memory after the resizing but that just seems like a waste.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Vectors never shrink.

tractor fanatic
Sep 9, 2005

Pillbug
Works for me. Thanks.

UraniumAnchor
May 21, 2006

Not a walrus.

Avenging Dentist posted:

Vectors never shrink.

code:
#include <vector>
#include <iostream>

using namespace std;

int main() {
        vector<int> a(20), b;

        a.reserve(40);

        cout << a.size() << " " << a.capacity() << endl;

        a = std::move(b);

        cout << a.size() << " " << a.capacity() << endl;
}

Output:

20 40
0 0
Am I misunderstanding something?

I realize it's not a common case, but hey.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

UraniumAnchor posted:

Am I misunderstanding something?

I realize it's not a common case, but hey.

Move semantics for STL containers essentially destroy the original container's storage and shunt the new container's storage into it. You can do the same sort of thing with swap in C++03. See the shrink-to-fit idiom:

code:
std::vector<int> v;
// fill v up with some stuff
std::vector<int>(v).swap(v);
(Also, I'm pretty sure it's undefined whether clear() destroys the container's storage).

Avenging Dentist fucked around with this message at 05:53 on May 13, 2010

Adbot
ADBOT LOVES YOU

Zerf
Dec 17, 2004

I miss you, sandman

Avenging Dentist posted:

(Also, I'm pretty sure it's undefined whether clear() destroys the container's storage).

Which of course causes compiler vendors to implement it differently. Don't know about GCC today, but for the PS3 clear() meant "delete memory". For the 360/PC, memory was not deleted. Yay for working with undefined behavior while making real-time systems!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply