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
whoknew
Sep 18, 2004


oh shit
im lit



Jo posted:

Goddamnit. :doh:

Works now. Thank you.
A lot of the time in C++ you can get around a problem by changing the way you wrote the code slightly, but if you don't know why that change fixed it, you shouldn't assume that it's actually fixed. You definitely clobbered something, somewhere.

Adbot
ADBOT LOVES YOU

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->
I'm working on the third UVa problem, and I've figured out how to do it on paper, but I just can't work out how to create the algorithm. The only thing I've come up with so far is a very convoluted combination of for loops with static two-dimensional arrays, and huge if statements, and it crashes if I put in any two of the same number. I'm thinking that there must be an easier way, but my first-year C++ knowledge probably just isn't broad enough to know what method to use. Can someone throw me an idea to research? I was thinking this would be a case for a struct, but I have no idea.

Jo
Jan 24, 2005

:allears:
Soiled Meat

whoknew posted:

A lot of the time in C++ you can get around a problem by changing the way you wrote the code slightly, but if you don't know why that change fixed it, you shouldn't assume that it's actually fixed. You definitely clobbered something, somewhere.

Perhaps there is a latent problem. I'm really not sure _why_ the problem was happening in the first place. As some stated, this should not have happened.

The full source code for the triangulation functions is here.

http://pastebin.com/m5ff26445

The tests for the triangle functions, line functions, and points functions have passed. The tests for the swap edge have passed. Tests for find common edge have passed. (Though common edge tests were not terribly extensive.)

I hesitate to post the full code because I'd hate to force anyone to shuffle through it all. :xd:

EDIT: There are a few nasty code-bits. The lack of breaks in the swapEdge function is vestigial -- debugging efforts that haven't been cleaned up completely.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
This would be somewhat less painful to debug if you were using references more and pointers less. Also, sometimes you delete[] the return value from getPoints(), and sometimes you don't.

Returning a std::list (as opposed to a pointer to a malloc'ed one, or some other way of passing the information back) is a bad idea, but it's probably not a memory bug.

Anyway, that's what I see in a quick scan.

Jo
Jan 24, 2005

:allears:
Soiled Meat

rjmccall posted:

This would be somewhat less painful to debug if you were using references more and pointers less. Also, sometimes you delete[] the return value from getPoints(), and sometimes you don't.

Returning a std::list (as opposed to a pointer to a malloc'ed one, or some other way of passing the information back) is a bad idea, but it's probably not a memory bug.

Anyway, that's what I see in a quick scan.

I'll keep these in mind if I rewrite everything. (Likely) Thank you very much for your time.

ani47 posted:

The only problem I think I can see (apart from memory leaks and overuse of new/delete) is you don't clear your trianglesToCheck deque after to add them to the other triangles deque here:

code:
for( int i=0; i < trianglesToCheck.size(); i++ ) {
       legalizeTriangle( trianglesToCheck.at(i), &triangles );
       triangles.push_back( trianglesToCheck.at(i) );
}

YES! Excellent! Thank you so much for noticing that. Good eye.

Jo fucked around with this message at 19:03 on Jan 2, 2009

ani47
Jul 25, 2007
+
I can't see how you could stomp over your 'std::deque <Triangle*> triangles;' from the code (seeing as it's at the top of your stack so you would need to underrun something to write over it). You sure it isn't just the debugger being crap or was your program actually crashing in legalizeTriangle?

The only problem I think I can see (apart from memory leaks and overuse of new/delete) is you don't clear your trianglesToCheck deque after to add them to the other triangles deque here:

code:
for( int i=0; i < trianglesToCheck.size(); i++ ) {
       legalizeTriangle( trianglesToCheck.at(i), &triangles );
       triangles.push_back( trianglesToCheck.at(i) );
}

Bitruder
Nov 29, 2003

Majoring in connect the dots and colouring
I have a class with member variables of type bool, std::string, int, double, std::vector< std::vector<double> > and std::vector< OtherClass > where OtherClass is all std::vector<double>'s.

I want to save objects of this class to a file and be able to store them. Ideally, something like:
code:
 saveObject(myObject, "filename");  myObject = loadObject("filename"); 
My classes contain no pointers. How can I do this? I'm on Linux if that matters. I'll be loading the objects back into the same program so it will be fully aware of the class and could instantiate class objects the normal way.

Thanks!

Edit: Just came across boost::serialization. I already use several boost libraries so this could work well.
http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html

Bitruder fucked around with this message at 18:32 on Jan 2, 2009

Vanadium
Jan 8, 2005

Bitruder posted:

My classes contain no pointers.
Yes, they do, inside the vectors. :shobon:

Nippashish
Nov 2, 2005

Let me see you dance!

Anunnaki posted:

I'm working on the third UVa problem, and I've figured out how to do it on paper, but I just can't work out how to create the algorithm. The only thing I've come up with so far is a very convoluted combination of for loops with static two-dimensional arrays, and huge if statements, and it crashes if I put in any two of the same number. I'm thinking that there must be an easier way, but my first-year C++ knowledge probably just isn't broad enough to know what method to use. Can someone throw me an idea to research? I was thinking this would be a case for a struct, but I have no idea.

This problem actually has a very nice solution if you approach it from the right angle. Here's a hint: how many possible solutions are there for an instance of this problem? If there are few enough possible answers you can find the optimal one by just computing them all and selecting the best one.

Thug Bonnet
Sep 22, 2004

anime tits ftw

Is the find method for std::string supposed to ignore '\0'?
This doesn't work:
code:
char cstr[] = {'t','e', 's', 't', '\0', 'f'};
std::string cppstring += str;
int pos;

if((pos = client_message.find('\0')) != std::string::npos)
	std::cout << pos << std::endl;

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Strings are null-terminated, you know. :psyduck:

Thug Bonnet
Sep 22, 2004

anime tits ftw

Avenging Dentist posted:

Strings are null-terminated, you know. :psyduck:

Yes, I know ;)

I'm recieving multiple messages over a socket that are terminated with '\0', and I need to be able to split them up on their boundries.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Put it in a vector or something. Appending a string with nulls in it isn't even going to do what you want, since it'll terminate at the first null.

hexadecimal
Nov 23, 2008

by Fragmaster

Nippashish posted:

This problem actually has a very nice solution if you approach it from the right angle. Here's a hint: how many possible solutions are there for an instance of this problem? If there are few enough possible answers you can find the optimal one by just computing them all and selecting the best one.

Aha. This is what is called "Bruteforce approach". The way I did this, is that I had a vector of pairs between string and number of movements necessary for that particular string. There are only 6 possible combinations of bins. So for each test case I create 6 pairs, and compute number of movements needed. Then just sort the vector using STL's sort algorithm, and voila, you are done.

The trickiest part is to make comparator function for this, which allows me to sort pairs. If you don't specify custom comparator function, then this wont work because it won't find < operator.

In my solution I had this vector: vector<pair<string,unsigned long long> > pos;
And after populating it I sorted it using this function: sort( pos.begin(), pos.end(), cmp );

And cmp is:
code:
bool cmp( const pair<string,unsigned long long> & a, const pair<string,unsigned long long> & b )
{
     if( a.second != b.second ) return a.second < b.second;
     else return a.first < b.first;
}
Notice that cmp also does lexicographical sort if the number of movements is same for some 2 configuration of bins.

And all thats needed to print out solution is: cout<<pos[0].first<<" "<<pos[0].second<<endl;

I recommend you read http://www.cppreference.com/ as it is a great quick reference site for STL. However I don't think its exhaustive, but it has saved my rear end a lot of times for these algo problems.

hexadecimal fucked around with this message at 00:47 on Jan 3, 2009

Thug Bonnet
Sep 22, 2004

anime tits ftw

Avenging Dentist posted:

Put it in a vector or something. Appending a string with nulls in it isn't even going to do what you want, since it'll terminate at the first null.

Ah, gotcha, didn't realize it stopped appending at '\0' too. Thanks!

Vanadium
Jan 8, 2005

Thug Bonnet posted:

Ah, gotcha, didn't realize it stopped appending at '\0' too. Thanks!

Everything with C strings stops at '\0'. The '\0' is the only way for anything that uses C strings to find out where the string ends.

Standish
May 21, 2001

Avenging Dentist posted:

Put it in a vector or something.
Or just use std::string::append(const char*, size_t) to tell it explicitly how many characters to append:
code:
char cstr[] = {'t','e', 's', 't', '\0', 'f'};
std::string cppstring;
cppstring.append(cstr, 6);

Avenging Dentist
Oct 1, 2005

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

Standish posted:

Or just use std::string::append(const char*, size_t) to tell it explicitly how many characters to append:
code:
char cstr[] = {'t','e', 's', 't', '\0', 'f'};
std::string cppstring;
cppstring.append(cstr, 6);

That'll put the string in an inconsistent state.

Standish
May 21, 2001

Avenging Dentist posted:

That'll put the string in an inconsistent state.
How do you mean? Sure, you now have cppstring != cppstring.c_str() which can trip you up if you're not paying attention but that's not really "inconsistent"; what c_str() returns is quite clearly explained in the STL docs...

Standish fucked around with this message at 01:13 on Jan 3, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
I was pretty sure the standard required that char*s passed to std::string did not contain null, but apparently not. Nevertheless, the best solution would probably be to just use std::find in <algorithm>, especially since that won't create an extra copy.

Thug Bonnet
Sep 22, 2004

anime tits ftw

Is the common solution here to end your messages with some other control character? \n?

floWenoL
Oct 23, 2002

hexadecimal posted:

And all thats needed to print out solution is: cout<<pos[0].first<<" "<<pos[0].second<<endl;

Why sort if all you need is the max element?

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

Thug Bonnet posted:

Is the common solution here to end your messages with some other control character? \n?

There are basically two options:

1. Change the format of the message so that the message itself tells you how long the variable-length data is (e.g. prepend the number of characters in the message to each message). If this is for real-world use you need to do sanity checking here, though.

2. Store the incoming message buffer in a data structure that does not interpret its contents as a string (such as a vector) and then search for the \0 character like you were planning to do before. There's nothing wrong with having a data structure, even a raw array, containing characters with some \0s in the middle of it. You just can't use these in a context where they will be interpreted as "string" rather than "series of characters".

hexadecimal
Nov 23, 2008

by Fragmaster

floWenoL posted:

Why sort if all you need is the max element?

Good point, but in this problem it doesn't really matter. Also you want to use min_element here.

Anunnaki: Here is how you would use min_element instead of sort:

code:
struct comporator
{
       bool operator()( const pair<string,unsigned long long> & a, const pair<string,unsigned long long> & b  )
       {
             if( a.second != b.second ) return a.second < b.second;
             else return a.first < b.first;
       }
};

....

vector<pair<string,unsigned long long> >::iterator i = min_element( pos.begin(), pos.end(), comporator() );
cout<<i->first<<" "<<i->second<<endl;


Also, I would like to recommend a book called "Programming Challenges" which is written by some professors from UVa. Here is amazon link: http://www.amazon.com/Programming-Challenges-Steven-S-Skiena/dp/0387001638/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1230959540&sr=8-1

hexadecimal fucked around with this message at 06:13 on Jan 3, 2009

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->

Nippashish posted:

This problem actually has a very nice solution if you approach it from the right angle. Here's a hint: how many possible solutions are there for an instance of this problem? If there are few enough possible answers you can find the optimal one by just computing them all and selecting the best one.

Thanks to everyone who responded to my question, but I figured it out doing every calculation and finding the smallest one. However, this problem's sample output is a little confusing. If two possibilities both yield the smallest number of movements, then you're supposed to display the one that comes first alphabetically. However, for the second sample input, "BGC" and "CBG" both yield the minimum, and since "BGC" comes first alphabetically, my algorithm outputs that; but the sample output says "CBG."

Can someone explain to me why "CBG" is alphabetically superior to "BGC"?

Avenging Dentist
Oct 1, 2005

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

Anunnaki posted:

Can someone explain to me why "CBG" is alphabetically superior to "BGC"?

That would be because your algorithm is wrong.

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->

Avenging Dentist posted:

That would be because your algorithm is wrong.

No, their output is saying "CBG" is alphabetically superior to "BGC."

Avenging Dentist
Oct 1, 2005

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

Anunnaki posted:

No, their output is saying "CBG" is alphabetically superior to "BGC."

No, your scoring algorithm is wrong. CBG does not have the same number of moves as BGC. It's easy to see this by inspection.

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->

Avenging Dentist posted:

No, your scoring algorithm is wrong. CBG does not have the same number of moves as BGC. It's easy to see this by inspection.

Hmm, going back and doing it on paper, "CBG" doesn't even yield 50 with my algorithm (which was basically to find the highest number in the column and add the other two), but doing it a couple different ways I found one that does yield 50. Now I'm confused about what their algorithm is, if not to calculate every single possibility for all 9 cells (rather than all 6 possibilities using one algorithm). In which case, I have some rewriting to do (for the third time :().

hexadecimal
Nov 23, 2008

by Fragmaster

Anunnaki posted:

Hmm, going back and doing it on paper, "CBG" doesn't even yield 50 with my algorithm (which was basically to find the highest number in the column and add the other two), but doing it a couple different ways I found one that does yield 50. Now I'm confused about what their algorithm is, if not to calculate every single possibility for all 9 cells (rather than all 6 possibilities using one algorithm). In which case, I have some rewriting to do (for the third time :().

There is no algorithm for computing number of moves for some configuration. It is just straightforward addition. You are probably over complicating this terribly in your mind.

Consider variables b#L, where # is number of bin, and L is the type of bin. For BGC the number of moves needed to get that is b1g + b1c + b2b + b2c + b3b + b3g because you are moving green and clear ones from first one, then blue and clear from second bin, and blue and green from third bin.

Here is a clue from my solution:
code:
unsigned long long b1b, b1g, b1c, b2b, b2g, b2c, b3b, b3g, b3c;
while( cin>>b1b>>b1g>>b1c>>b2b>>b2g>>b2c>>b3b>>b3g>>b3c )
.......
pos.push_back( pair<string,unsigned long long>("BGC", b1g + b1c + b2b + b2c + b3b + b3g ));
There are 6 total possible configurations that you do this for.

shodanjr_gr
Nov 20, 2007
Say I have a function:

code:
myFunction(Myclass* pointerOut)
{
 pointerOut = new Myclass();
}
and then

code:
int main()
{
Myclass* myPointer = NULL;
myFunction(myPointer);
myPointer.doSomething(); // <- the pointer is still null here
}
What am I doing wrong? I want to be able to pass the pointer as an argument to a function, create an object on that pointer, then keep it around after the function call.

hexadecimal
Nov 23, 2008

by Fragmaster

shodanjr_gr posted:

Say I have a function:

code:
myFunction(Myclass* pointerOut)
{
 pointerOut = new Myclass();
}
and then

code:
int main()
{
Myclass* myPointer = NULL;
myFunction(myPointer);
myPointer.doSomething(); // <- the pointer is still null here
}
What am I doing wrong? I want to be able to pass the pointer as an argument to a function, create an object on that pointer, then keep it around after the function call.

Pointers are passed by value (a new copy of myPointer is create when passed to myFunction, and that copy has no effect on myPointer inside the main). myFunction has no effect on myPointer.

shodanjr_gr
Nov 20, 2007

hexadecimal posted:

Pointers are passed by value (a new copy of myPointer is create when passed to myFunction, and that copy has no effect on myPointer inside the main). myFunction has no effect on myPointer.

How can I work around this?

hexadecimal
Nov 23, 2008

by Fragmaster

shodanjr_gr posted:

How can I work around this?

I am not sure you can? Or you can use pointer of pointer. Why are you doing it this way anyway?

shodanjr_gr
Nov 20, 2007

hexadecimal posted:

I am not sure you can? Or you can use pointer of pointer. Why are you doing it this way anyway?

Long story short, I am writing a deserialization method for some class im working on (application for a network simulator) and I want it to return the number of bytes it read from a buffer, but I also want it to return an instance of the object its deserializing (duh!). So I figured i'd do it this way.

Avenging Dentist
Oct 1, 2005

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

hexadecimal posted:

I am not sure you can? Or you can use pointer of pointer. Why are you doing it this way anyway?

Sigh. If you don't know the answer to something, you don't need to post. Someone who knows more about the topic at hand will probably come along with a real answer. That said:

You use a reference to a pointer, like so:
code:
void foo(int *&i)
{
    i = new int;
}
Also, your code won't compile, since "->" is used instead of "." with pointer types.

hexadecimal
Nov 23, 2008

by Fragmaster

shodanjr_gr posted:

Long story short, I am writing a deserialization method for some class im working on (application for a network simulator) and I want it to return the number of bytes it read from a buffer, but I also want it to return an instance of the object its deserializing (duh!). So I figured i'd do it this way.

So why not return a pair?

code:
pair<int,obj*> func()
{
    ... 
    pair<int,obj*> ret( 5, new obj() );
    return ret;
}
EDIT: Ahh ok, I didn't know about *& myself.

Lexical Unit
Sep 16, 2003

hexadecimal posted:

I am not sure you can?
Er? You could pass the pointer by reference if you really wanted.

myFunction(Myclass*& pointerOut)

Beaten of course.

shodanjr_gr
Nov 20, 2007

Avenging Dentist posted:

Also, your code won't compile, since "->" is used instead of "." with pointer types.

Yeah, sorry about that...slip of the keyboard while typing it out.


Thanks for the replies all :)

Adbot
ADBOT LOVES YOU

hexadecimal
Nov 23, 2008

by Fragmaster
Why do I get segmentation fault when I do this:

code:
foo ** a;
*a= new foo();
foo is just some simple struct.

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