|
vanjalolz posted:Ha Ha what the hell? Do Boost pointers actually add anything useful to warrant such terrible syntax? They're not different pointer types, it's just a metafunction that yields a regular pointer. Avenging Dentist posted:Quick question, which hopefully That Turkey Story can answer: is there a library to support properties in C++ (a la C#)? If not, I'm going to write one... I though I had this discussion with you but maybe not. I actually made a library for properties in C++ a couple years ago but it's impossible to make one without overhead except in certain cases unless you complicate your encapsulating class definition (and in the case of empty types, you're out of luck). The reason is that if you want the standard . syntax, you generally have to make a dummy object that needs access to the encapsulating class, which you can't directly do without storing redundant information. A quick example of a common situation that causes problems is a container with begin, end, and size properties. To get around having to have the internal property object need access to the encapsulating object to pull out iterator data, you can just store the begin iterator inside of the begin property and store the end iterator inside of the end property, but then what do you do for size? Often size isn't explicitly store in containers at all and is instead just calculated on demand, such as internally doing end() - begin() when you call size() for std::vector (which is very common). The issue is, how does your size property dummy object get access to the begin and end iterators? It can't directly access them because they are contained in some object other than itself that it does not directly or indirectly encapsulate. Since you are going to be using overloaded operator = and an overloaded conversion operator for access and because . itself is not overloadable, you have no way of passing a reference to the data transparently during the access. Instead you have to do something like always store a reference to the encapsulating object from within your property, which just needlessly bloats the size of your encapsulating object and also adds some additional overhead such as for initalization. Not only that, but the maker of the type now needs to explicitly initialize the property in his constructor, which makes his own code more complex. Another trivial example that causes problems is a bunch of properties that map into a bit-field. You can't stick part of the bit-field in each member, so for each of those properties, you're going to be taking some damage. Now all of a sudden you need O(N) redundant self-references stored indirectly in your object, where N is the number of bits you are accessing, with each property generally taking sizeof(void*) space a piece, and each needing to be separately initialized in the constructor. Then there is the issue of properties with virtual accessors. If you accept all of the problems mentioned above and continue on, virtual functions add even more hassles. Why? Because now the implementation of your accesses needs to be a call that is forwarded to a virtual function in your encapsulating object, since if you just directly make the functions virtual in your property dummy object, deriving from the encapsulating object won't allow you to override your property's virtual functions (and even if you could, it would still imply that each of your properties with virtual accessors has its own vtable pointer, which again would cause hell to the size and initialization of your overall object). All of these problems are pretty much show-stoppers, at least with the common C++ philosophy. If you still want to go on, what I ended up doing, just because I refused to be defeated and wanted to see something remotely similar to properties even though I'd never actually use it, is overload a binary operator for accessing the name of the property. Then, since that function has access to both the encapsulating object and whatever object you are using for a name, you can create a simple temporary during the access which holds a reference to the encapsulating data and that has overloaded operator = and conversion. I chose operator ->* since it made the most sense. So in the end, for the no overhead approach you can get access like: code:
|
# ? May 15, 2008 20:11 |
|
|
# ? Jun 9, 2024 00:35 |
|
... and there was a proposal to the committee about adding language support for properties. It died a horrible death. So don't hold your breath.
|
# ? May 15, 2008 20:26 |
|
That Turkey Story posted:There's always the option of using memory offsets to communicate among properties!
|
# ? May 15, 2008 20:35 |
|
That Turkey Story posted:
I just realized that Qt doesn't actually do this at all - all its "properties" do is declare attach a name to the getter/setter functions that can be used from language bindings that actually support properties; from C++ you still have to use the functions.
|
# ? May 15, 2008 21:40 |
|
code:
Never mind. Some leftover code was tampering with the Actor I was trying to Update. Iori Branford fucked around with this message at 09:29 on May 17, 2008 |
# ? May 17, 2008 02:03 |
|
You need to provide more context. P.S. Don't do "typedef struct", it's not necessary in C++.
|
# ? May 17, 2008 02:21 |
|
edit: Issue resolved so you may want to just skip over this unless you're interested in this kind of stuff... End result was sockets weren't getting properly closed and select() on them was making memory allocation go through the roof. This may well belong in a linux questions thread I'm not sure... I am however sure it's given me a lot of headache after spending a couple of weeks on and off trying to solve it. In fact maybe I should just be posting a thread as it's not exactly a simple question, but I'm just going to shoot here anyway as it seems most appropriate. Situation: I'm developing a chat server/client in parallel... The client is made in flex to be embedded into peoples web pages, but has no issues. The server is made to run on a linux server(developed in eclipse using the cygwin CDT oolchain, then rebuilt on the target server), uses berkeley sockets and a single thread, using a select statement to check for updated sockets. The issue however is with after a random amount of time, generally ranging from 3-8 hours, it gets killed by oom killer. The issue occurs in both the forking daemon process version I made, and the "normal" active process. I've been trying to trawl over logs and have gone over all the relevant code in the main loop that could be causing a memory leak but have no clue... I could intercept the kill signal to do some processing there, but I believe it'd be a bad idea to just ignore it... If I was to intercept the signal what kind of data should I try to pull before letting the app die? How would I get it. Including some of the relevant source as well as the dmesg log of one of the crashes should anybody be willing to take a peek: Main loops and non-trivial functions used by it(not including the actual message processing calls... The crash occurs regardless of actual socket activity code:
code:
Creepy Doll fucked around with this message at 11:18 on May 20, 2008 |
# ? May 20, 2008 03:51 |
|
Haven't taken the time to read your code, but change "while true" to "for (int i = 0; i < 10; ++i)" or something so that it'll only run a few times. Then run it through valgrind with the --leak-check flag and it should tell you where the most obvious leaks are.
|
# ? May 20, 2008 04:19 |
|
JoeNotCharles posted:Haven't taken the time to read your code, but change "while true" to "for (int i = 0; i < 10; ++i)" or something so that it'll only run a few times. Then run it through valgrind with the --leak-check flag and it should tell you where the most obvious leaks are. Sweet, I wasn't aware of valgrind, installing it now and going to see what it comes up with, thanks.
|
# ? May 20, 2008 05:14 |
|
Is Splint still worth using, or does Valgrind covers everything that Splint does?
|
# ? May 20, 2008 07:02 |
|
Welp, there was a couple of minor errors along the lines of delete'ing where I should've delete[]'d, but they weren't in the main loop, but rather in the shutdown and such... Fixed those and down to 0 errors + 4 suspended errors from 1 context... Got the program running in the background now and hoping for the best, but considering the severity of the errors that were there(a total of maybe 200-300 bytes worth of allocated memory that wasn't properly unallocated), I doubt it's fixed... We shall see. Either way, great tool and thanks for pointing to it! Should help in the future too.
|
# ? May 20, 2008 07:28 |
|
Creepy Doll posted:Welp, there was a couple of minor errors along the lines of delete'ing where I should've delete[]'d, but they weren't in the main loop, but rather in the shutdown and such... Hmm, that gives me an idea: Valgrind checks for actual errors, but also for possible memory leaks, which are things which are allocated during the program that aren't freed when the program ends. If your program keeps allocating memory in each loop, but doesn't free it correctly until shutdown, Valgrind wouldn't catch it (because it IS freed at shutdown). That would give exactly the symptoms you see - if you run it for a while with "while (true)" the memory will grow without bound, but if you limit it to a few iterations Valgrind won't report a problem. I'm not sure if Valgrind can give a sensible report on leaks if the memory actually gets exhausted while it's running. You could try going back to "while (true)" and see what happens (or better yet, see if you can find anything about it in the Valgrind docs). Or maybe try commenting out all your cleanup code on exit so that Valgrind will report more "leaks", some of which will be bogus and some of which will be your actual leak.
|
# ? May 20, 2008 08:21 |
|
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ I'll have a look at that, however, there's barely any actual allocation going on that isn't handled by the stl classes... Most of my user and room management is all done with stl::list and stl::map... Which I would like to hope are leak free. welp, allowing it to run for an hour or so I got this code:
I never concerned myself with memory management beyond making sure anything I allocated I got rid of down the line, so I'm not 100% sure of the meaning of this report, but I think it means 498 bytes total in 24,292,669 blocks? That would mean a lot of blocks allocated with 0 memory? Why would this be happening? edit: I'm going to give massif a shot to see if it can tell me what the hell is allocating all that memory, because it sure as hell isn't being done by any new/mallocs explicitly within my program. edit^2: And the results are in... For some reason extra poo poo is allocated to the stack in what massif describes as extra-heap(B)... massif docs posted:• The number of extra heap bytes allocated at that point. This reflects the number of bytes allocated in excess of The actual data(a couple of samples of it... it's just a linear increase throughout the program): code:
Creepy Doll fucked around with this message at 08:55 on May 20, 2008 |
# ? May 20, 2008 08:33 |
|
If you're stuffing stuff into a list but never removing it from a list, that's a "leak" in the sense that you're adding more and more stuff and never getting rid of it. So that could be your problem. EDIT: most things you put into an STL data structure use the copy constructor, so if you create a local object on the stack it automatically copies it onto the heap for you, which is where the new memory comes from: code:
I'm really not sure how to interpret the summary it gave you - could it be 24,292,669 blocks of 498 bytes each? (I didn't think that was how it reported them, but I can't figure any other sensible way to interpret that.) Have you tried using the --leak-check=full flag it gave? (I meant to tell you to use that from the start, but I forgot the exact syntax so I just said "--leak-check" - sorry.) JoeNotCharles fucked around with this message at 08:44 on May 20, 2008 |
# ? May 20, 2008 08:41 |
|
I did the leak check full flagit didn't give any additional info... User connections are also logged as are room creations and neither of them is happening unexpectedly. I appear to be onto something now... It seems none of this actually occurs until the first user disconnects, and then memory starts getting consumed... It's just extremely slow without something like massif increasing the consumed memory by huge amounts while profiling it... I guess something is probably wrong with my method of removing a user or disconnecting a socket... edit: Looks like I found the problem. For some dumb reason when checking for received bytes on the socket I was checking less than 0 and more than 0, but not for zero(correct shutdown of the socket). Oddly enough this was not an issue on the cygwin setup running off my pc... I assume cygwin uses winsock to emulate berkeley sockets and somewhere in that process a correct shutdown(0 received) becomes an error(-1)... Either way, thanks a lot for the tips, without them I'm sure this would've taken a lot more work. Edit^2: Down to no leaked memory so looks like it's all good. I guess select()ing on a correctly closed socket is apparently a very bad thing. Creepy Doll fucked around with this message at 11:16 on May 20, 2008 |
# ? May 20, 2008 09:10 |
|
I'm trying to write a merge sort function, but I keep getting errors that have me stumped. At the very end of my merge_sort I call a function merge() which returns a string*, yet when I call my function like this: code:
error: no matching function for call to 'merge(std::string*&, std::string*&)' the prototype of my merge function is: code:
heh...got it, I am stubborn with my main files and I always like to define the functions first instead of putting the prototype then defining them after my main. It turns out merge needed to be above merge_sort Viper2026 fucked around with this message at 02:18 on May 21, 2008 |
# ? May 21, 2008 01:38 |
|
Viper2026 posted:
Since you solved your own problem, I'd like to just add that you don't need that even/odd business; you can just split down the middle (length / 2). If the length is odd, one part will be one element larger than the other, but that's not a problem.
|
# ? May 21, 2008 12:13 |
|
Viper2026 posted:I'm trying to write a merge sort function, The real solution to your problem is to stop right there, and use std::sort() and/or std::merge() instead. Check out the gratis and very extensive documentation on Dinkumware's STL <algorithm> page if you don't know the STL's API well. If you do that in future, you won't struggle with the details of algorithms that have already been written 1000 times. The code you wrote in hours would have taken minutes or seconds.
|
# ? May 21, 2008 13:58 |
|
That sure will go over well in a data structures/algorithms class.
|
# ? May 21, 2008 17:01 |
|
Viper2026 posted:
|
# ? May 21, 2008 17:33 |
|
Ok, here's a question. I have a function (below) that accepts a string that's a path to a file, and then opens that file and does stuff. This function can be called from source A or source B. If source A calls this function, and the path has an extended character in it (like "é"), the file fails to open. If source B does the same thing, it works. My thought is that the encoding of the string from source A is somehow messed up - any thoughts about how to fix this? (I'm running this on Windows).code:
String from source A was utf8-encoded. Converted it to ansi and it worked! Edit 2: New Question: Anyone know how to correctly pass cyrillic characters in a path to ifstream? Stormtrooper fucked around with this message at 19:30 on May 21, 2008 |
# ? May 21, 2008 17:46 |
|
Vanadium posted:That sure will go over well in a data structures/algorithms class. If you were doing software development in the real world, then Ping's answer would be correct 99.999...9 % of the time. The biggest boon to productivity is access to libraries that have been thoroughly used, bug-tested/fixed, and tons of space/time efficiency tricks that you never would have thought of or taken forever to get right.
|
# ? May 21, 2008 19:23 |
|
Stormtrooper posted:Edit 2: New Question: You need to construct a wstring containing the path, then pass that to a wifstream. Cyrillic characters are outside of the ASCII set, so you have to use wide characters. ifstream cannot eat UTF-8 characters.
|
# ? May 21, 2008 19:36 |
|
cliffy posted:If you were doing software development in the real world, then Ping's answer would be correct 99.999...9 % of the time. The biggest boon to productivity is access to libraries that have been thoroughly used, bug-tested/fixed, and tons of space/time efficiency tricks that you never would have thought of or taken forever to get right. All the hay-we-are-using-c++-in-the-industry seem to hate the STL anyway and roll their own non-generic containers Also I think if you are posting on SA about how to implement your own container you are probably not doing software development in the real world.
|
# ? May 21, 2008 20:03 |
|
Wuen Ping posted:You need to construct a wstring containing the path, then pass that to a wifstream. Cyrillic characters are outside of the ASCII set, so you have to use wide characters. ifstream cannot eat UTF-8 characters.
|
# ? May 21, 2008 20:03 |
|
Vanadium posted:That sure will go over well in a data structures/algorithms class. Yeah...exactly this I need to write this myself and the prof is pretty good about catching people trying to copy/paste. I gave up on the array approach because it was was simply too complicated and am using vector<string>'s now. But I am still having a problem in that my code does not actually sort my list. My code is here: http://rafb.net/p/dLKodz88.html I call merge_sort on the first 10 elements of the vector (the file parsing is all correct) When I run it, it all seems to work, but when I go to print out the first 10 elements of my vector they do not appear to be sorted at all. If anyone can take a look and offer any insight into what my problem might be, I'd appreciate it
|
# ? May 21, 2008 23:32 |
|
Your merge_sort returns a vector, but you aren't storing the result. I'm guessing your just printing the unsorted vector again. Look into passing by reference (that will also solve the stack overflow that will occur when you pass a vector of non-trivial size into a recursive sorting function.)
|
# ? May 21, 2008 23:50 |
|
Paniolo posted:Your merge_sort returns a vector, but you aren't storing the result. I'm guessing your just printing the unsorted vector again. Look into passing by reference (that will also solve the stack overflow that will occur when you pass a vector of non-trivial size into a recursive sorting function.) thanks a lot....I must learn to catch my own stupid mistakes like this code:
9. terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check Would changing my function prototypes to something like vector<string> merge_sort(vector<string> *list, int number){ and then calling as vector<string> sorted_list = merge_sort(&names2, 10); fix this? EDIT: leaving my current code as is and sorting then printing for 100 it crashes at 65, and for 1000 it crashes at 513 Viper2026 fucked around with this message at 00:11 on May 22, 2008 |
# ? May 21, 2008 23:55 |
|
Viper2026 posted:works partially, but result 9 prints:
|
# ? May 22, 2008 01:26 |
|
Mustach posted:std::out_of_range is thrown when you call at() with an index that's less than 0 or greater than or equal to the vector's size. So does this mean I'm not correctly handling my sizes somewhere in my code? (I've looked at it for a while now and I can't really see where the problem is, if you might be able to at least give me a hint from the code I linked above I would appreciate it)
|
# ? May 22, 2008 01:34 |
|
Viper2026 posted:So does this mean I'm not correctly handling my sizes somewhere in my code? code:
As an aside, you should really reduce the unnecessary copies you're making of your vectors. I count 3 copies of the full vector and 8 copies of the left/right vectors for every step of the merge sort. Avenging Dentist fucked around with this message at 01:45 on May 22, 2008 |
# ? May 22, 2008 01:43 |
|
Avenging Dentist posted:
Hmph....yeah I thought that might be an issue, but someone in one of my previous questions said that shouldn't be an issue So do I want to handle each one differently depending if list.size() is odd or even?
|
# ? May 22, 2008 01:57 |
|
You don't need to have any special handling. middle and number-middle, respectively should be sufficient for all cases.
|
# ? May 22, 2008 02:05 |
|
That works, thanks a lot
|
# ? May 22, 2008 02:10 |
|
pthreads question: Is there any disadvantage to creating lots and lots of threads over the course of a program's execution, if only a couple will exist at any given time? The context is that I'm writing an app that does asynchronous communication over UDP. Since UDP is unreliable, certain packets that are not ACK'ed after a timeout need to be re-sent. The way I'm currently handling this is: - send the packet - spawn a thread which sleeps for the timeout interval - when the thread wakes, it checks if the ACK has been received yet, if not it calls a timeout handler, which repeats this process. So every packet that might need to be re-sent gets its own timeout monitor thread. There are only going to be a few (like, 1-5) of these packets pending at any given time, but the program may run for a very long time, so there could easily be hundreds or thousands of short-lived threads created over the course of the program. Is there any problem with doing this, as long as I make sure to either detatch or join each thread? I could certainly consolidate timeout handling into one thread, but that would make the code messier and more complicated, so I'm inclined to avoid that unless there is a good reason to do it.
|
# ? May 24, 2008 00:42 |
|
Smackbilly posted:pthreads question: You could just keep a few of them around and reuse them, instead of creating new ones over and over again. But don't. Do the thing that makes the code messier. It is a local mess (and only if you code it dumbly), not a global mess, so it is fine.
|
# ? May 24, 2008 01:01 |
|
Smackbilly posted:I could certainly consolidate timeout handling into one thread, but that would make the code messier and more complicated, so I'm inclined to avoid that unless there is a good reason to do it. It doesn't, really. All you need is a list of packets you have sent out but not received ACKs for yet. When you receive an ACK, remove that packet from the list. Also keep track of the last sent time and resend it every so often. Also, you can average the total round trip time of the last, say 10 packets, and use that as the timeout interval, to avoid sending to frequently or not frequently enough depending on network conditions.
|
# ? May 24, 2008 03:38 |
|
Here's a dumb question with added : I do most of my coding in C#, some Perl, some VB/VBA. I did a semester of C++ in college but we never progressed beyond console applications and some minor pointer fun. Since I'm fed up with knowing the basics of C++ but not enough to do anything useful, I've decided to relearn it, and to that end I'm reading Accelerated C++. I use Visual Studio 2005 for C# stuff, and I've really grown to like it as a development environment. I'm planning on using Visual C++ 2005 to work along with the book, but I know there are some ways in which it's not like a "standard" C++ compiler. For example, the blank project I've just created has "#include "stdafx.h" at the top and the compiler doesn't like it if I remove it. Trouble is, I don't know if that's a minor VS quirk or just one of many ways VC++ differs from what I'll find in textbooks. In a nutshell, what I'd like to know is what I should be aware of when learning C++ using Visual Studio. I'd rather know of any common issues ahead of time rather than wait to run into them.
|
# ? May 24, 2008 20:25 |
|
Just create an empty project in VS2005. There's very little difference in terms of the compiler when writing C++ in Visual Studio (templates are kinda hosed up though).
|
# ? May 24, 2008 21:58 |
|
|
# ? Jun 9, 2024 00:35 |
|
Stdafx.h is a precompiled header file. You can stick all your library includes in there (from C, STL, Windows, etc.) and it significantly reduces the time of compiling the rest of your project. You can safely delete stdafx.h and specify a new header to precompile later on, but it might require some tweaking of the project settings (even after you delete it, the default project settings still tell the compiler to precompile "stdafx.h" so you have to remove all references to it. Pretty annoying.) That's all just IDE stuff, in terms of the Microsoft C++ compiler, it's pretty standard stuff. The template problems that were so bad in earlier versions have been fixed to the point where you can use the more experimental boost modules like Spirit just fine. If you create a new blank project in the IDE, add a new blank .cpp file and copy and paste the code from any C++ textbook it will run. Most of the differences (to the naked newbie eye) between VC++ and gcc are in the preprocessor (different predefined macros, although some like __FILE__ and __LINE__ are the same.) Another significant difference is the handling of 64-bit integers, in VC++ you'd declare them with "__int64" whereas in gcc it's "long long." You shouldn't run into many problems at your level, though. Edit: woops, VC++ accepts "long long" now, too.
|
# ? May 24, 2008 23:00 |