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
Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Well for one thing, you should be returning when argc != 2.

Adbot
ADBOT LOVES YOU

Runaway Five
Dec 31, 2007
I hate gays almost as much as I hate good posting. Also, God is good. Amen
Quick question, is the following okay in a sense it won't cause memory leaks?

void * pX = new foo; // Allocate a foo object, save it as a void pointer.
// Do a bunch of stuff.
.
.
.
.
delete (pX);

My question is, is it okay to allocate an object dynamically, keep a pointer to it as a VOID POINTER, and then call delete on that void pointer. Will C++ Garbage collection be able to deal with that?

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
The effect of deleteing a void* is undefined by the standard. Most implementations will probably free the memory but probably will not call the destructor.

Don't do that.

Mustach fucked around with this message at 16:25 on Sep 24, 2009

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
Also, keep in mind that C++'s manual memory management is not "garbage collection", hence why you have to explicitly call delete. If one did want some form of automatic memory management, there are smart pointers in the standard (which suck) and in boost (which are ok), with the pro being that they deallocate deterministically, and the con that they can not deal with circularly linked structures (cyclic graphs etc). If you do want full-on garbage collection, there are a couple freely available GCs, though I couldn't speak to their quality as I haven't used them.

haveblue
Aug 15, 2005



Toilet Rascal

Runaway Five posted:

Quick question, is the following okay in a sense it won't cause memory leaks?

Why are you using a generic pointer for an object you obviously know the type of?

csammis
Aug 26, 2003

Mental Institution
Maybe reinterpret_cast was feeling underrepresented in his codebase?

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


Avenging Dentist posted:

Well for one thing, you should be returning when argc != 2.

That was it, thanks! :downs::hf::commissar:

Edit: OK, running into another problem with those command-line arguments. Before, I could just start up the server part of my program, fire up the client and it'd get the right arguments (not really sure where argc and argv come from to be honest). Now that my client half is contained in a class and is being called by another main class, it's not getting the right arguments. I am not sure what to do besides have the main class pull those arguments itself and then pass them to the other class since it seems like you can only pick up those arguments at the very beginning of your program, but this isn't giving me the right values. What could I do to fix this?

HondaCivet fucked around with this message at 21:23 on Sep 24, 2009

BattleMaster
Aug 14, 2000

Mustach posted:

The effect of deleteing a void* is undefined by the standard. Most implementations will probably free the memory but probably will not call the destructor.

Don't do that.

I read that new/delete is internally the same as malloc/free (confirm/deny?) which keeps track of how big the allocated memory chunk is so it should be able to delete it.

haveblue posted:

Why are you using a generic pointer for an object you obviously know the type of?

Yeah, you can just cast it if you need it as a void pointer somewhere.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

BattleMaster posted:

I read that new/delete is internally the same as malloc/free (confirm/deny?) which keeps track of how big the allocated memory chunk is so it should be able to delete it.

Don't ever rely on this

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

BattleMaster posted:

I read that new/delete is internally the same as malloc/free (confirm/deny?), which keeps track of how big the allocated memory chunk is, so it should be able to delete it.

(added punctuation to clarify how I'm parsing your sentence)

In pretty much every standard environment, yes, the built-in operator new and operator delete are implemented using malloc and free. Note that new expressions invoke the constructor associated with the type and arguments you specify, while delete expressions call the destructor associated with the type of its pointer argument. You can generally (but not portably) assume that deleteing a void* will free the memory associated with your allocation, but will not call any destructors. Nonetheless, it's a bad idea; if you know the type of the object (pretty much always true), you should at least cast to that type before deleting it.

Note that, even if you want to play this game with single objects allocated through operator new, you almost certainly don't want to play this game with arrays allocated through operator new[]; compiler behavior there is much more erratic.

BattleMaster
Aug 14, 2000

Otto Skorzeny posted:

Don't ever rely on this

Oh hell no, deleting a void pointer is really drat stupid.

Fecotourist
Nov 1, 2008
Three different versions of a vector dot product member function, assuming N=3 and T=float for the moment:

code:
    // _c is a boost::array<T,N> holding the vector's components
    T dotA(const Vec &r) const { return _c[0]*r._c[0] + _c[1]*r._c[1] + _c[2]*r._c[2]; }
    T dotB(const Vec &r) const {
        T rv=0;
        for(int i=0; i<N; i++) rv += _c[i] * r._c[i];
        return rv;
    }
    // bf means boost::fusion
    T dotC(const Vec &r) const {
        return bf::fold(bf::transform(_c, r._c, std::multiplies<T>()), 0, std::plus<T>());
    }
Under g++ 4.2.1 with -O3, I find that dotA() and dotC() are equally fast (woohoo), while dotB() is slower by a factor of 1.7.
Looking at the assembly, the only substantive difference is that dotA() and dotC() are compiled into single-precision multiply instructions (fmuls) while dotB() gets the (slower) double-precision fmul.

Is there a good reason for the compiler to insist on double-precision math in the case of an explicit for loop?

On the other machine I've tested with slightly different versions of CPU, g++, and boost, all the multiplies are mulss (SSE single precision) and the CPU times for the three versions are more like 1:2:4 (boohoo). The fusion stuff is apparently not inlined quite as thoroughly.

OddObserver
Apr 3, 2009

rjmccall posted:

(added punctuation to clarify how I'm parsing your sentence)

In pretty much every standard environment, yes, the built-in operator new and operator delete are implemented using malloc and free.
Not quite. delete also performs pointer adjustment in the multiple-inheritance case --- trying to delete a 2nd sub-object works (well, at least if there is a vtable..), while free'ing it will crash/corrupt the heap.

floWenoL
Oct 23, 2002

Fecotourist posted:

Is there a good reason for the compiler to insist on double-precision math in the case of an explicit for loop?

Can you try setting rv = _c[0]*r._c[0] directly and then iterating on [1,2], and/or setting rv to [0,1] and iterating on just 2?

Also, just a hunch, but I would also try setting rv to "0.f" instead of "0".

Fecotourist
Nov 1, 2008

floWenoL posted:

Can you try setting rv = _c[0]*r._c[0] directly and then iterating on [1,2], and/or setting rv to [0,1] and iterating on just 2?

Initializing rv to the first term and looping over the second and third produces one single- and two double-precision multiplies.
Initializing rv to the sum of the first two terms using a single-iteration for loop to add the third results in all three being SP. The loop must be getting removed at a very early stage in the compiler pipeline, making this case equivalent to hand-coded.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Isn't gcc 4.2.1 really old and has a lovely optimizer?

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

BattleMaster posted:

Oh hell no, deleting a void pointer is really drat stupid.

Not the void pointer thing, any sort of 'equivalence' between malloc/new and free/delete

C++ memory management operators may or may not be implemented using C memory management functions, but it isn't in the standard and it will bite you in the rear end if you try to rely on it (eg. deallocating memory with free() that was allocated with operator new, even if the object is POD)

e: beaten like a redheaded stepchild

UberJumper
May 20, 2007
woop
Okay so i am right now taking a random gamedev class in c++ (i need 4th year credits and my university offers nothing). Now the prof is some "respected" programmer from the game development industry and basically gave us a quick run through C++ on how to do things. Things that don't sit very well with me.

He told us this:
When making classes, we should declare all the header files we are using in the .cpp file and not in the .h file. Because otherwise this leads to many many programs including stuff we don't need. Really? I thought we were always supposed to do the includes in the .h file.

code:
E.g.
//.h file
// declare class 
class foo
{
std::string blah();
}

Then in the .cpp file:
#include "foo.h"
#include <string>
#include <vector>
#... etc ....

// do functions
He says the above was is much easier on the compiler.

Also he raged on about how STL is essentially garbage and is so bloated and slow. I know STL is not as fast as just pure C++, but am i really going to hell for using it? If so really honestly what is a better option aside from using my own arrays and such when working with GameDev? He suggested we look heavily into ATL if we are writing games for windows.

Also he gave us this odd example:

code:
class Engine
{
private:
std::vector<std::string> objectList;

public:
<snip 80 lines of code>
void UpdateEverything();
void UpdateObject(std::string objectName);
}

//cpp

void Engine::UpdateEverything()
{
if(somerandomvariable == true)
{
 std::string a("HELLO");
 UpdateObject(a);
}

for(int a = 0; a < objectList.size(); a++)
{
 std::cout << objectList[a] << std::endl;
}
}

void Engine::UpdateObject(std::string objectName)
{
 objectList.push_back(objectName);
}
He said that once the it hits the loop it will always crash. Since once the program leaves the scope of a, the vector doesnt know where a is. and did not belive me when i said otherwise. I don't have a visual studio compiler at the moment, but in g++ it does not crash. Please tell me this guy is just crazy :<

Avenging Dentist
Oct 1, 2005

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

UberJumper posted:

When making classes, we should declare all the header files we are using in the .cpp file and not in the .h file. Because otherwise this leads to many many programs including stuff we don't need. Really? I thought we were always supposed to do the includes in the .h file.

You are very wrong and he is very right. This is usually the only point game programmers get right though, probably largely because game code is a huge loving mess and the only way to make compile times sensible is to micromanage dependencies. That said, you should do it anyway.

UberJumper posted:

Also he raged on about how STL is essentially garbage and is so bloated and slow. I know STL is not as fast as just pure C++, but am i really going to hell for using it? If so really honestly what is a better option aside from using my own arrays and such when working with GameDev? He suggested we look heavily into ATL if we are writing games for windows.

STL is inappropriate for a lot of game engines because of how allocators work pre-C++0x. If he actually suggested ATL and you aren't just misunderstanding him, then :lol:, since ATL is primarily useful for talking with COM objects.

As usual, game programmers don't actually know C++, they just know stuff people told them 10 years ago.

Also he gave us this odd example:

UberJumper posted:

He said that once the it hits the loop it will always crash. Since once the program leaves the scope of a, the vector doesnt know where a is. and did not belive me when i said otherwise. I don't have a visual studio compiler at the moment, but in g++ it does not crash. Please tell me this guy is just crazy :<

He's not crazy, he's just an average game developer. Yeah I went there. :nyd:

Bhaal
Jul 13, 2001
I ain't going down alone
Dr. Infant, MD

UberJumper posted:

He told us this:
When making classes, we should declare all the header files we are using in the .cpp file and not in the .h file. Because otherwise this leads to many many programs including stuff we don't need. Really? I thought we were always supposed to do the includes in the .h file.
That's correct. Take this example:

code:
// Monkey.h
#include "Banana.h"  // Grabs the banana class definition

class Monkey
{
  void useBanana(Banana*);  
};
code:
//Monkey.cpp
#include "Monkey.h"  // Grabs the monkey and banana definitions

void Monkey::useBanana(Banana* b)
{
  b->stuff(); 
  etc...
}
code:
// Banana.h
class Banana() {...};
code:
//Banana.cpp
#include "Banana.h"
//stuff...
code:
//Aardvark.h, Alligator.h, ... Zebra.h
#include "Monkey.h" // grabs the monkey.....AND banana definitions
code:
//Aardvark.cpp, Alligator.cpp, etc.
//These classes may interact with Monkey but most do not interact with Banana
What you've got is a bunch of animal classes, and a banana class. The banana class gets used by let's say only the monkey and ape classes. However, all animals will have to know about eachother because they may have to interact. And because all animal headers include the monkey header, they also will include the banana header (even though they don't need to know about it). Then Banana.h has a change made to it and you need to recompile ALL animals. Instead you could do it this way:
code:
// Monkey.h
class Banana; // we cannot invoke Bananas in here, ie. no inline "Banana->stuff()" 

class Monkey
{
  void useBanana(Banana*); // this is okay
//  inline void useBananaAgain(Banana* b) {b->foo();} // ERROR! we only have the declaration, 
                                                         not definition of class Banana
};
code:
//Monkey.cpp
#include "Monkey.h" // Banana gets declared
#include "Banana.h" // Now Banana is defined

void Monkey::useBanana(Banana* b)
{
  b->stuff();  // We can invoke class Banana because it has been defined from the include
  etc...
}
Technically you can change all the animal classes to do the same with Monkey.h and any others, but sometimes you do want to inline stuff so it depends on the case (but the default, especially for big projects, should be the 2nd method).

I don't know about the STL thing. If the game needs a lean-and-mean container to hold 80 bazillion items that get churned through every game loop, then I guess there's a case for that. I just hope his thrust with that example isn't to get in the habit of building every sorting algorithm, container class, etc from the ground up.

Bhaal fucked around with this message at 03:22 on Sep 25, 2009

Fecotourist
Nov 1, 2008

Avenging Dentist posted:

Isn't gcc 4.2.1 really old and has a lovely optimizer?

Point taken, but this seems pretty lovely for only 2 years ago.

guenter
Dec 24, 2003
All I want out of life is to be a monkey of moderate intelligence who wears a suit. That's why I've decided to transfer to business school!
Does anyone have any tips on using AMD CodeAnalyst? Or maybe another debugger I should be using? Here's an example of my output:

code:
CS:EIP   	Symbol + Offset                                   64-bit 	Timer samples 	
0x41bd50 	std::_Checked_base<boost::shared_ptr<Entity> *>                  5.1           	
0x40e8e0 	std::vector<D3DXVECTOR3,std::allocator<D3DXVECTOR3> >::size     4.42          	
0x40bb70 	std::_Move_cat<EffectPass *>                                    4.35          	
0x40d190 	std::_Vector_const_iterator<stdext::_Hash<stdext::_Hmap_traits<... 4.35          	
0x401100 	std::_Iterator_base_aux::_Has_container                         3.74          	

5 functions, 38 instructions, Total: 323 samples, 21.96% of samples in the module, 0.81% of total session samples
Knowing a lot of time is spent in the stl/boost is all well and good but I'm more interested in knowing how much time is being spent in code I actually wrote and what I might be doing that is causing stuff like _Checked_base to get called a lot, whatever the gently caress that is.

guenter fucked around with this message at 05:08 on Sep 25, 2009

That Turkey Story
Mar 30, 2003

Avenging Dentist posted:

You are very wrong and he is very right. This is usually the only point game programmers get right though, probably largely because game code is a huge loving mess and the only way to make compile times sensible is to micromanage dependencies. That said, you should do it anyway.

...What? No. Anything the header file needs to include should be done so in the header, anything the cpp file needs to include should be in the cpp file. The problem is that most people include things they don't need to from the header file such as full definitions of types instead of just their declarations. You aren't gaining anything on compile times by simply stripping all needed includes from the header itself since your translation units that include the header will have to manually include all of them anyway. Everything the class definitions need should be included in the header file, anything the class's function and member definitions require should just be included once in your cpp file as opposed to in the header file. The only thing you accomplish by taking all includes out of the header file is brining potential implementation details to the surface by requiring users of the header to needlessly manually include dependencies. You will not save on compile times.

UberJumper
May 20, 2007
woop

Avenging Dentist posted:

He's not crazy, he's just an average game developer. Yeah I went there. :nyd:

So does that mean it wouldn't work? :|?

OH GOD MY HEAD *explodes*

He said ATL, since ATL has its own container classes and such, and said they implement things alot better. I am still confused. I understand the STL point, but did not realize the .cpp header thing. Thanks.

Avenging Dentist
Oct 1, 2005

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

That Turkey Story posted:

Anything the header file needs to include should be done so in the header, anything the cpp file needs to include should be in the cpp file.

I'm talking about people who get as far as the first part of that sentence and then ignore the rest of it. All the time, I see people just #include files in another header that should be implementation details. Literally 100% of the time I am seeing this.

Bhaal
Jul 13, 2001
I ain't going down alone
Dr. Infant, MD

That Turkey Story posted:

You will not save on compile times.
I think what the prof is referring to is where people put nearly everything A.cpp needs to include inside of A.h. He was meaning it "saves compile time" to avoid this habit because then when you edit a header file and build, it won't needlessly rebuild a bunch of unaffected translation units that had the touched header nested somewhere in an include-chain.

That Turkey Story
Mar 30, 2003

Avenging Dentist posted:

I'm talking about people who get as far as the first part of that sentence and then ignore the rest of it. All the time, I see people just #include files in another header that should be implementation details. Literally 100% of the time I am seeing this.

Yeah, true, but I think he was trying to say that you literally shouldn't include any files from header files which is just wrong. Coming from the game industry, I actually worked at a place where you weren't supposed to include header files and instead we had a few big monolithic header files that included large groups of dependencies. Each translation unit included one or more of these, often needlessly so, when only one or two small things were needed. It was terrible and a distributed rebuild across 20 computers took over an hour. The best part is they decided to only include stuff from cpp's in order to combat compile times.

:sigh:

Edit:

Bhaal posted:

I think what the prof is referring to is where people put nearly everything A.cpp needs to include inside of A.h. He was meaning it "saves compile time" to avoid this habit because then when you edit a header file and build, it won't needlessly rebuild a bunch of unaffected translation units that had the touched header nested somewhere in an include-chain.


Yeah, if that's what he meant then good.

raminasi
Jan 25, 2005

a last drink with no ice
Does anyone know a good XML library? I'm using MSVS and Microsoft has some XML thing but I don't think it's what I need (it needs to already be installed on targeted machines, and the right version too...I think). I'm primarily interested in writing XML, not reading it.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Writing XML is really easy.

Also your complaint about Microsoft's XML library is silly, since that's the same issue with every shared library ever. I'm 99% sure that MSXML lets you redistribute the files. The real issue you should have with MSXML is that the interface is the usual COM abomination (or something close to it).

If you're using XML as a way to serialize data, then Boost.Serialization is what you want.

Avenging Dentist fucked around with this message at 17:53 on Sep 25, 2009

Avenging Dentist
Oct 1, 2005

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

That Turkey Story posted:

:words:

My criterion is "can I use the stuff in this header in another translation unit by including this and only this header"?

Vanadium
Jan 8, 2005

Avenging Dentist posted:

My criterion is "can I use the stuff in this header in another translation unit by including this and only this header"?

Come on, the example the guy gave is not even going to compile.

Vinterstum
Jul 30, 2003

Avenging Dentist posted:


He's not crazy, he's just an average game developer. Yeah I went there. :nyd:

He's teaching a "random gamedev class". He's not an average game developer, he's a failed one (Actually, given his "example" it sounds doubtful he's ever worked with C++ in his life).

Generalization fail.

(Yes, yes, feeding the trolls, I know).

Vinterstum fucked around with this message at 19:36 on Sep 25, 2009

Avenging Dentist
Oct 1, 2005

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

Vinterstum posted:

He's teaching a "random gamedev class". He's not an average game developer, he's a failed one (Actually, given his "example" it sounds doubtful he's ever worked with C++ in his life).

One could argue that escaping the game industry is a mark of success. :pwn:

Vinterstum
Jul 30, 2003

Avenging Dentist posted:

One could argue that escaping the game industry is a mark of success. :pwn:

I'm leaning more towards "Those who can, do; those who can't, teach." in this case. Since he's pretending to still be in the industry and everything.

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


No one knows the answer to the question I made in my edit? :(

Avenging Dentist
Oct 1, 2005

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

HondaCivet posted:

No one knows the answer to the question I made in my edit? :(

argc and argv are just regular local variables (well ok they're arguments) in main. To get them somewhere else, you have to pass them around.

HondaCivet
Oct 16, 2005

And then it falls
And then I fall
And then I know


Avenging Dentist posted:

argc and argv are just regular local variables (well ok they're arguments) in main. To get them somewhere else, you have to pass them around.

I did that . . . I worked out why it wasn't working though, apparently the program had the wrong settings in VS. I figured this out by actually looking inside argv and seeing what it was storing. At least I learned something today I guess.

UberJumper
May 20, 2007
woop

Avenging Dentist posted:

argc and argv are just regular local variables (well ok they're arguments) in main. To get them somewhere else, you have to pass them around.

I thought in visual studio they were stored as __argv and __argc globals?

Avenging Dentist
Oct 1, 2005

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

UberJumper posted:

I thought in visual studio they were stored as __argv and __argc globals?

__argc and argc are not the same thing.

Adbot
ADBOT LOVES YOU

torb main
Jul 28, 2004

SELL SELL SELL
Alright, junior varsity programmer's question: so I'm implementing a BST in C++ for the first time in three years. I know all of my other functions are correct, but my remove function behaves incorrectly. As an example of how remove is called, consider the following code:

code:
BinarySearchTree B1;
B1.insert(1);
B1.insert(2);
B1.insert(1);
while(B1.remove(2))
{ continue; )
For some reason, I get the follow runtime error:

code:
*** glibc detected *** ./MAIN: double free or corruption (fasttop): 0x083bb1b0 ***
I've been staring at this for ages and checked the logic in remove at least twice.

This is the code for the remove function: http://pastebin.com/m39637273

This should be so simple, but it's been so long since I've looked at C++ I'm sure I'm just missing something stupid. Thanks in advance to anyone who takes the time to take a look :)

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