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

Anunnaki posted:

Because running this with the input:
code:
3 3
1 2 3
4 5 6
7 8 9
outputs this:
code:
There are 3 boxes, with 3 dimensions each. They are as follows:
Box 0 = 2818244 2822192 0
Box 1 = 2822192 2818244 1406475607
Box 2 = 7 8 9

I don't think you understand how memory deallocation works. It is in no way required to change the values of the deleted memory, and in most cases, it won't. In the rare case that it does (e.g. debug versions of libraries), the values will generally be replaced with a consistent hex value like 0xDEADBEEF. Chances are that by the time you get to output, that memory has been reclaimed by another part of the system.

If you want to actually check for leaks, run valgrind on your code.

Adbot
ADBOT LOVES YOU

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->

Avenging Dentist posted:

I don't think you understand how memory deallocation works. It is in no way required to change the values of the deleted memory, and in most cases, it won't. In the rare case that it does (e.g. debug versions of libraries), the values will generally be replaced with a consistent hex value like 0xDEADBEEF. Chances are that by the time you get to output, that memory has been reclaimed by another part of the system.

If you want to actually check for leaks, run valgrind on your code.

Oh, I see. Thanks. :)

So, if I add more to this program, should I deallocate that array at the end of the program, or does it not matter as long as I'm not going to use it for something else (since the program will terminate anyway)?

Edit: On a side note, is it common to come across weird poo poo on pastebin?

http://pastebin.com/m14cf38e

Cosmopolitan fucked around with this message at 09:25 on Jan 18, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
You should always deallocate your memory when you're done with it.

Smackbilly
Jan 3, 2001
What kind of a name is Pizza Organ! anyway?

Avenging Dentist posted:

You should always deallocate your memory when you're done with it.

This is of course correct, however it is also true that thanks to the magic of virtual memory, allocated memory will not persist past the end of your program, whether or not you deallocate it. So there are some circumstances in which you may allocate something that you never deallocate and that's not really a problem - e.g. a singleton object that is lazy-allocated when first requested and might be used right up until exit.

Vanadium
Jan 8, 2005

Guys, I have nothing to really contribute to the thread, but can you reassure me that trying to learn to use boost.spirit is going to be less of a pain with C++0x and concepts and everything? :smith:

I am usually not afraid of templates but when my 1k source file results in 40k of error messages, I feel like I am just doing it wrong. And I really want to like boost.spirit.

Jo
Jan 24, 2005

:allears:
Soiled Meat
I'm having a hell of a time linking CGAL. One of the google links actually points here to the forums, but I don't see an actual library name. (I.E. -lcgal) Do I really need to use cmake, or is there a linker command like -lcgal that will work?

EDIT: -lcgal != -lCGAL :downs:

Jo fucked around with this message at 23:25 on Jan 18, 2009

Chuu
Sep 11, 2004

Grimey Drawer
I have a huge tree of abstract classes defining certain properties of messages. I can't really edit this tree. The leafs are concrete implementations, and basically because of the tree all what's left to do is write custom serialize/deserialize methods.

These things are stupidly tedious to write. I want to write a default implementation that'll work for 90% of the cases. I know how to write it. The question is how do I actually get it into my code.

The key here though -- I cannot edit the abstract tree. The easy solution of dumping the default implementation somewhere in the tree is not available to me.

What I've considered:

1. The "dreaded diamond" Have the default implementation class inherit from the base class, implement the methods, and have the concrete leaf class inherit from it.

Besides the whole "MI is evil" arguments that may/maynot be true, I don't trust myself to know C++ well enough to implement this without subtle bugs when you're going to have one leg of the tree virtual, and one non-virtual. Quite honestly, I'm not even 100% sure what the implications of a virtual and non-virtual base class is, when those classes share a common non-virtual base class.

2. Dumping the implementations in a static class, and somehow using those implementations.

Can you do this in C++? Essentially some way to tell the compiler "this pure virtual method's implementation is OVER THERE IN THAT CLASS, it's static so you don't have to instantiate it, just use it please".

3. Something else I'm not aware of.

Any other options?

Chuu
Sep 11, 2004

Grimey Drawer
Sort of related to the above.

Are local variables in static methods implicitly static, i.e. do they remember their values across all method calls and will blow up in your face if you're not careful using them in threaded code?

That Turkey Story
Mar 30, 2003

Chuu posted:

1. The "dreaded diamond" Have the default implementation class inherit from the base class, implement the methods, and have the concrete leaf class inherit from it.

Besides the whole "MI is evil" arguments that may/maynot be true, I don't trust myself to know C++ well enough to implement this without subtle bugs when you're going to have one leg of the tree virtual, and one non-virtual. Quite honestly, I'm not even 100% sure what the implications of a virtual and non-virtual base class is, when those classes share a common non-virtual base class.
What you are describing isn't a diamond or even multiple inheritance at all. Multiple inheritance is when one single type inherits from two or more different types (such as having a left and a right base). There is nothing hairy you have to worry about with what you are describing.

Chuu posted:

2. Dumping the implementations in a static class, and somehow using those implementations.

Can you do this in C++? Essentially some way to tell the compiler "this pure virtual method's implementation is OVER THERE IN THAT CLASS, it's static so you don't have to instantiate it, just use it please".
I'm not sure what you mean here, there is no such thing as a static class in C++.

Chuu posted:

3. Something else I'm not aware of.

Any other options?

You can always implement the pure virtual member functions. This doesn't require you to change the bases themselves, just add associated definitions I.E.:

code:
class base
{
public:
  virtual void foo() = 0;
};

//Add a default implementation
void base::foo()
{
  // Do stuff
}

class child
  : public base
{
public:
  void foo() { base::foo(); } // Call the default implementation
};

Chuu posted:

Sort of related to the above.

Are local variables in static methods implicitly static, i.e. do they remember their values across all method calls and will blow up in your face if you're not careful using them in threaded code?
No, local variables in static member functions behave the same as those in other functions.

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:

I'm not sure what you mean here, there is no such thing as a static class in C++.

I think a static class is just a really obtuse name for "namespace". :)

Avenging Dentist
Oct 1, 2005

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

Vanadium posted:

Guys, I have nothing to really contribute to the thread, but can you reassure me that trying to learn to use boost.spirit is going to be less of a pain with C++0x and concepts and everything? :smith:

I am usually not afraid of templates but when my 1k source file results in 40k of error messages, I feel like I am just doing it wrong. And I really want to like boost.spirit.

Are you using Spirit 2 or Spirit Classic?

Chuu
Sep 11, 2004

Grimey Drawer

That Turkey Story posted:

What you are describing isn't a diamond or even multiple inheritance at all. Multiple inheritance is when one single type inherits from two or more different types (such as having a left and a right base). There is nothing hairy you have to worry about with what you are describing.

I'm probably not describing it correctly. The tree looks something like this

code:
 Message <--- Base class, pure virtual
    |
[Huge tree]
    |
SpecificMessage : Ser() and DeSer() only pure virtual methods left.
SpecificMessage only has 2 pure virtual functions left to implement, which are defined in Message. What I was thinking about is something like this:

code:
   Message----------------
      |                  |
   [Huge tree]        SerDeSer[Contains impelmentation of Ser() and DeSer()]
      |                  |
      |------------------
   SpecificMethod
So basically I can have complete concrete classes just by inheriting from both the tree and SerDeSer.

I cannot change anything in the "Message" class or the Huge Tree because it's a constraint imposed on me, not because I think C++ will not allow it.

I want to do something like this because there are dozens of these bastards to implement, with more to come, and 90% could use the same implementation.

Chuu fucked around with this message at 00:52 on Jan 19, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Why not just make a class template?

code:
template<typename T>
struct basic_butt : T
{
    void Ser() { cout << "farts"; }
    void DeSer() { cout << "poops"; }
};

typedef basic_butt<SpecificMessage> SpecificMethod;

Avenging Dentist fucked around with this message at 01:19 on Jan 19, 2009

Smackbilly
Jan 3, 2001
What kind of a name is Pizza Organ! anyway?

Chuu posted:

I'm probably not describing it correctly. The tree looks something like this

code:
 Message <--- Base class, pure virtual
    |
[Huge tree]
    |
SpecificMessage : Ser() and DeSer() only pure virtual methods left.
SpecificMessage only has 2 pure virtual functions left to implement, which are defined in Message. What I was thinking about is something like this:

code:
   Message----------------
      |                  |
   [Huge tree]        SerDeSer[Contains impelmentation of Ser() and DeSer()]
      |                  |
      |------------------
   SpecificMethod
So basically I can have complete concrete classes just by inheriting from both the tree and SerDeSer.

I cannot change anything in the "Message" class or the Huge Tree because it's a constraint imposed on me, not because I think C++ will not allow it.

I want to do something like this because there are dozens of these bastards to implement, with more to come, and 90% could use the same implementation.

You could always do it by composition. Have each SpecificMessage class contain an object of type SerDeSer and then just copy-paste a pass-through implementation of Ser and DeSer that call the equivalent function on the contained SerDeSer object.

Depending on implementation details you may want to re-architect this so that SerDeSer doesn't inherit from message at all, and just takes a reference to a Message object to work on.

Chuu
Sep 11, 2004

Grimey Drawer
Doing it via composition would work and is miles better than copying pasting wholesale, but it's not really an elegant solution. Ideally I'd like something where I could have "no code" implementations of a concrete class, i.e. "class SpecificMethod : public ClassInTree, public virtual SerDeSer{};" is a complete implementation.

Really if the "virtual" keyword does what I think it does the MI solution would work very well, but I can't find anything about what virtual inheritance means other than via examples in diamonds, where both base classes are virtual. I've learned the hard way many times that never assume something in C++ is going to do what you think it should do though :(

Dentist : I don't have freedom to change the external interface to messages.

Avenging Dentist
Oct 1, 2005

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

Chuu posted:

Dentist : I don't have freedom to change the external interface to messages.

There's absolutely nothing in my code that changes the interface?

There was a typo.

Avenging Dentist fucked around with this message at 01:19 on Jan 19, 2009

Chuu
Sep 11, 2004

Grimey Drawer

Avenging Dentist posted:

There's absolutely nothing in my code that changes the interface?

I'm really confused at what this code is doing then. Doesn't SpecificMessage remain pure virtual, i.e. you broke the interface for any class that is trying to create an instance of it?

Chuu
Sep 11, 2004

Grimey Drawer
Re : typo

Did you mean something like this?

code:
 [Message]
     |
 [huge tree]
     |
   [parent]
     |
  SpecificMessage
code:
template<typename T>
struct basic_butt : T
{
    void Ser() { cout << "farts"; }
    void DeSer() { cout << "poops"; }
};

-------------------------------------------
SpecificMessage.h:

typedef basic_butt<parent> SpecificMessage;
Would this work? That's close enough to a "no-code" implementation for me

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Chuu posted:

Besides the whole "MI is evil" arguments that may/maynot be true, I don't trust myself to know C++ well enough to implement this without subtle bugs when you're going to have one leg of the tree virtual, and one non-virtual. Quite honestly, I'm not even 100% sure what the implications of a virtual and non-virtual base class is, when those classes share a common non-virtual base class.

The usual implementation technique for virtual inheritance is that the virtual method table for the virtually-inheriting class indicates the offset to the base class. To be more specific, if I have:

code:
class A { ... };
class B : A { ... };
class C : virtual A { ... };
class D : B, C { ... };
Then the memory layout will be something like this (EDIT: set up the inclusion properly):

pre:
[[[A....]B....][C....]D....]
where C must have a vtable pointer, and one of the components of that vtable tells you how to turn a C* into an A* (i.e. is probably an offset equal to sizeof(B)). Then anything which tries to reach an A from a C (e.g. the code in C) has to do the additional offsetting work every time. If the compiler happens to have the full implementation of a method of C when it's compiling D, it can eliminate that work for the function that's actually placed in the vtable, but I'm not sure how common that optimization is.

Anyway, you have three choices as I see it that don't involve too much boilerplate inside every downstream class definition.

1. As AD suggests, you can use a templated base class for all your implementations. This potentially screws you for constructing the base class, and I don't know how to fix that:

code:
template <typename T>
class SerDeSer : public T {
  void Ser() {}
  void DeSer() {}
};

class SpecificMessage : public SerDeSer<ActualDesiredBase> { ... }
2. You can have SerDeSer virtually inherit from Message. This is fairly clean but might have inescapable overhead concerns.

3. You can define the SerDeSer implementations in a macro and call it inside the class definitions. This involves macros and is therefore ugly, but it directly accomplishes what you want.

rjmccall fucked around with this message at 01:59 on Jan 19, 2009

Avenging Dentist
Oct 1, 2005

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

Chuu posted:

Would this work? That's close enough to a "no-code" implementation for me

It should work. It basically makes basic_butt into an arbitrary leaf in your big class tree.

rjmccall posted:

1. As AD suggests, you can use a templated base class for all your implementations. This potentially screws you for constructing the base class, and I don't know how to fix that

Just add a default-constructible base class in between the template class and the thing you actually want to inherit from.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Avenging Dentist posted:

Just add a default-constructible base class in between the template class and the thing you actually want to inherit from.

Well, I'm assuming that this convoluted hierarchy of message types involves more and more fields being added to the class; possibly some of these are const and intended to be initialized by the constructors. The optimal thing in this case would be to duplicate the base class's constructors, and that's what I don't know how to do in template-land. A real metaprogramming system would let you do this easily.

Chuu
Sep 11, 2004

Grimey Drawer
Thanks for the replies. I'll probably go with the template solution since it looks like it'll be almost impossible to shoot myself in the foot implementing it.

Wondering, aside from the above though, why would you choose one over the other? Performance wise it seems like the MI solution just involves one extra vtable lookup which is trivial compared to the cost of the actual function. Other than that I don't see many other implications.

edit : Ok, the constructor issue would be a big one. Luckily not an issue for me. Sort of curious if it is solvable in template-land though.

Chuu fucked around with this message at 02:07 on Jan 19, 2009

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Chuu posted:

Wondering, aside from the above though, why would you choose one over the other? Performance wise it seems like the MI solution just involves one extra vtable lookup which is trivial compared to the cost of the actual function. Other than that I don't see many other implications.

Well, it's two loads, and it makes casts require a null check, and it adds an extra pointer to every object — but yes, it's very unlikely to be a burden. The MI solution is probably the best if you aren't deathly worried about performance and you don't care about constructors.

Vanadium
Jan 8, 2005

Avenging Dentist posted:

Are you using Spirit 2 or Spirit Classic?

Spirit 2, of course. As soon as I heard about spirit 2 I dropped all attempts to understand spirit classic.

SneakySnake
Feb 5, 2006

by Y Kant Ozma Post
So I'm deployed to Iraq and trying to learn C++ in my downtime. I've used a lot of online tutorials, and have a few ebooks I've been learning out of. I've hit the point now where I understand the basics of functions, classes, arrays, and so on. I've gone through C++ Demystified and finished it, but I'm at the point now where I'm still a beginner but looking to move on to more complex stuff.

Does anyone have any suggestions on where to go from here? I'm stuck in the middle gap of things and I'm finding resources are either things I've covered or too advanced and over my head. I'm looking preferably for more online tutorials, since I've got a pretty limited access to books and software and stuff.

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.
Sadly, it seems like every online C++ tutorial is crap in some way or another, so you're limited to Thinking in C++ and the C++ FAQ Lite that are linked in the first post. They don't fit the tutorial format, but considering that you've gone through another book and have some grasp of the basics, you should be able to get far with them.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
More of a platform-specific question, but on Windows/Linux, will using blocking file IO within a thread block the thread, or the entire process?

csammis
Aug 26, 2003

Mental Institution
On Windows it'll only block the thread. This is why you do blocking I/O or heavy processing in a thread other than the UI thread, so the UI remains responsive to input while blocking is happening.

Windows threads are kernel threads, I'm not sure how user threads (like pthreads on Linux) work.

Vanadium
Jan 8, 2005

OneEightHundred posted:

More of a platform-specific question, but on Windows/Linux, will using blocking file IO within a thread block the thread, or the entire process?

Verify for yourself!

code:
#include <iostream>
#include <boost/thread.hpp>

void spam() {
  for (;;) {
    std::cout << 'f' << std::flush;
    boost::this_thread::sleep(boost::posix_time::seconds(1));
  } 
}

int main() {
  boost::thread ffff(spam);
  std::cin.get();
}
I was pretty sure our threads are kernel threads too. At least not the whole process is blocked.

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->
I decided to try to learn Vi, and just program in a Unix environment in general, and also so I could take a look at GMP. So far, GMP seems to be unnecessarily cumbersome. You can't use simple arithmetic or assignment operators, you can't return any of the GMP data types, since it calls by reference to functions, and you can't have it associate in any way with any non-GMP data type, or it yells at you for trying to convert it. I just gave up on it. Maybe I'll learn it some day in the future.

On the subject of Vi: Is it really an asset to know how to use it? I learned all the basics, I got syntax highlighting enabled, and I can use it effectively now for what it's meant for--but it basically just seems like it's emulating everything a good GUI text editor does, but without the buttons. Is there any advantage to using Vi + Command Line, vs. just using a GUI IDE?

Vanadium
Jan 8, 2005

Anunnaki posted:

I decided to try to learn Vi, and just program in a Unix environment in general, and also so I could take a look at GMP. So far, GMP seems to be unnecessarily cumbersome. You can't use simple arithmetic or assignment operators, you can't return any of the GMP data types, since it calls by reference to functions, and you can't have it associate in any way with any non-GMP data type, or it yells at you for trying to convert it. I just gave up on it. Maybe I'll learn it some day in the future.

This is why you use the C++ bindings instead :ssh:

Standish
May 21, 2001

csammis posted:

On Windows it'll only block the thread. This is why you do blocking I/O or heavy processing in a thread other than the UI thread, so the UI remains responsive to input while blocking is happening.

Windows threads are kernel threads, I'm not sure how user threads (like pthreads on Linux) work.
Linux pthreads are kernel threads too (or to be more exact, the Native Posix Thread Library which is the default implementation of the pthreads API on any non-ancient Linux is kernel-thread-based, and so was the LinuxThreads library which preceded it.)

Standish fucked around with this message at 22:12 on Jan 19, 2009

csammis
Aug 26, 2003

Mental Institution

Standish posted:

Linux pthreads are kernel threads too (or to be more exact, the Native Posix Thread Library which is the default implementation of the pthreads API on any non-ancient Linux is kernel-thread-based, and so was the LinuxThreads library which preceded it.)

Whoops, maybe I meant GNU Portable Threads. It's been several years since I did any Linux development :shobon:

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

csammis posted:

On Windows it'll only block the thread. This is why you do blocking I/O or heavy processing in a thread other than the UI thread, so the UI remains responsive to input while blocking is happening.
This is actually for a game, all asset loads are deferable but I'm trying to get the IO operations offloaded to another thread so they don't cause framerate hiccups. Abstracting asynchronous IO is messier than abstracting threads and just using blocking IO operations in preload tasks.

I really don't care if the IO thread stalls. I do care if the rendering thread stalls!

OneEightHundred fucked around with this message at 02:25 on Jan 20, 2009

Avenging Dentist
Oct 1, 2005

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

OneEightHundred posted:

This is actually for a game, all asset loads are deferable but I'm trying to get the IO operations offloaded to another thread so they don't cause framerate hiccups.

I wrote a resource management system for games that loads files in a worker thread and it works fine (though it's only been tested in Windows, since it uses DirectX). It's responsive even in debug mode where some of my file parsers are ridiculously slow (I need to fix that).

Hung Yuri
Aug 29, 2007

by Tiny Fistpump
Guys I'm dumb what am I doing wrong



code:
#include <stdio.h>
main()
{
printf("Joe Shmoe\n");
}

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
mv chall3.h chall3.c

Hung Yuri
Aug 29, 2007

by Tiny Fistpump

Avenging Dentist posted:

mv chall3.h chall3.c

Idk what mv is but I did that and nothing changed on ./chall3.c or .h (idk which we're supposed to save them as, someone told me not to save as .h)

Oh, yeah I know what that does now, but it still gives me the same issue in the image

Jo
Jan 24, 2005

:allears:
Soiled Meat

Gvaz posted:

Idk what mv is but I did that and nothing changed on ./chall3.c or .h (idk which we're supposed to save them as, someone told me not to save as .h)

mv is the *nix command for 'move'. It has the same functionality as rename. Your main function should be in a .c file, not in a header (.h) file.

EDIT: Haha! Caught you before the ninja edit.

Adbot
ADBOT LOVES YOU

Hung Yuri
Aug 29, 2007

by Tiny Fistpump
Someone said "it cant resolve printf because somehow its not linking in standard c library" :(

I cant vm on this machine or whatever. :[ And I can't get Msys to work (it just opens up a billion windows then crashes)

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