|
Haywood Japwnme posted:Paniolo suggested, a few posts up, that I should use a trie. Anyone have any suggestions for a good C++ implementation or library for trie? Preferably one that compiles in GNU. http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds
|
# ? Apr 23, 2012 19:43 |
|
|
# ? Jun 8, 2024 10:55 |
|
Brecht posted:gcc ships with a GNU implementation of a trie. Thanks, I saw that one and am trying out. Another question, what's the MySQL C++ connector of choice around here? I was looking at libmysqlcppconn but the documentation is a little iffy.
|
# ? Apr 24, 2012 04:39 |
|
Hopefully someone can help me with this. I'm writing a threaded application to mimic a very very simple course management system where each thread is a different user. So I complete the basic implementation my teacher wanted, and start adding extra features since that's 10 points of the grade. The current thread I'm adding is saving the courses you add between uses. So, the feature got implemented and worked great, except I realized I put the code where I split up into the threads which could cause an error during run-time, so I put a "initialize user" type thing in the main function to do this for me in a sequential way. Anyway, after changing it up, it just doesn't seem to work properly, so I check my map and stuff, it seems right, so I check to make sure things are being read in properly. Well, seems like something has gone horribly wrong: code:
code:
courseFile.txt posted:* PHY 101 5 0 Uh, what?
|
# ? Apr 24, 2012 06:08 |
|
Make sure your reading code is only running on one thread.
|
# ? Apr 24, 2012 06:23 |
|
This is before it creates the threads. If more than one things is running this ever, then C++ is then just actively trying to sabotage me. The code before this is includes, initialization of global shared variables, and an error check on args.
|
# ? Apr 24, 2012 06:32 |
|
What does getline contain?
|
# ? Apr 24, 2012 06:33 |
|
Suspicious Dish posted:What does getline contain? edit: so seperating them out into separate prints "fixes" it so that it displays properly. Which confuses me, since then I can't help wonder if it's affecting my map function which I use on the input: code:
code:
code:
Anyway, that leads me to believe that my map has one good element, one element that doesn't have a key, and then an element that uh...I don't know, ignores "=>" I guess? Is there some fundamental part of strings that I've failed to learn in my teachings (ie. strings are insane and do whatever the gently caress they want) as this is frustrating as all hell as the project is supposed to be "done". Master_Odin fucked around with this message at 07:06 on Apr 24, 2012 |
# ? Apr 24, 2012 06:36 |
|
It looks like you're getting input from a text file with windows-style line endings (they end in \r\n, where '\r' is a special control character that means "go back to the beginning of the current line" and '\n' is a newline), but your program is trying to parse the file as if it were using unix-style line endings (expecting just \n, no \r). In your first example, this would lead you to parse the line "* PHY 101 5 0" as "* PHY 101 5 0\r", so your code would be doing this: code:
C++ implementations are expected to deal appropriately with the line endings for the platform your program is compiled for, so this sort of problem most typically means that your professor created courseFile.txt on a Windows system and you're developing on a Linux/Mac system. Your options to fix it include:
|
# ? Apr 24, 2012 08:41 |
|
brosmike posted:It looks like you're getting input from a text file with windows-style line endings (they end in \r\n, where '\r' is a special control character that means "go back to the beginning of the current line" and '\n' is a newline), but your program is trying to parse the file as if it were using unix-style line endings (expecting just \n, no \r). Any idea why intro to C++ classes make people gently caress with iostream? It's not like you can ever use it in a real project because it sucks so much rear end, and it's actually completely not intuitive how it works at all.
|
# ? Apr 24, 2012 12:16 |
|
brosmike posted:answer hieronymus posted:Any idea why intro to C++ classes make people gently caress with iostream? It's not like you can ever use it in a real project because it sucks so much rear end, and it's actually completely not intuitive how it works at all. On this project, I swear, my teacher probably wanted us to roll our own semaphore implementation, rather than use the handy semaphore.h library, which she didn't mention existed at all ever. Master_Odin fucked around with this message at 18:46 on Apr 24, 2012 |
# ? Apr 24, 2012 17:20 |
|
Master_Odin posted:On this project, I swear, my teacher probably wanted us to roll our own semaphore implementation, rather than use the handy semaphore.h library, which she didn't mention existed at all ever. Uh... how would you recommend learning how to implement concurrency primitives?
|
# ? Apr 24, 2012 20:02 |
|
Master_Odin posted:My CSC department didn't bother imparting the fact that importing std namespace into all headers is bad practice either. I feel like I'm teaching myself a lot of the actual usage of the language through project assignments and my need to do things in some neat way then from class. I certainly hope your department is encouraging its students to seek out information like this (pragmatically useful but conceptually uninteresting) on their own. Assuming you plan to make a career out of this, you'll be spending a LOT of next few decades teaching yourself how to solve exactly these sorts of problems, and most people start out pretty bad at doing so and needing all the practice they can get. Most software development jobs you would actually want to have will expect you to be able to pick up a basic working knowledge of the "actual usage of the language" for whatever language you need in pretty short order without much in the way of formal classes (obviously mastery of a language is expected to take much longer, but is again done through mostly practice)
|
# ? Apr 24, 2012 22:14 |
|
shrughes posted:Uh... how would you recommend learning how to implement concurrency primitives? I wrote a small PHP/mySQL database driver, doesn't mean if I ever got a project, I'd use that over PDO. Clearly I'm ill suited for academia, and probably wrong about this, so I won't clutter up the thread with my ill advised stances on it. brosmike posted:I certainly hope your department is encouraging its students to seek out information like this (pragmatically useful but conceptually uninteresting) on their own. Assuming you plan to make a career out of this, you'll be spending a LOT of next few decades teaching yourself how to solve exactly these sorts of problems, and most people start out pretty bad at doing so and needing all the practice they can get. Master_Odin fucked around with this message at 01:11 on Apr 25, 2012 |
# ? Apr 25, 2012 01:02 |
|
I'm getting my rear end beat by Boost's upgrade locks while trying to use them with shared locks for read/write locking. The common method you'll find online for using those locks is: 1. For reading, used a shared lock 2. For reading and potentially writing, start with an upgradable lock and get a unique lock at the point of writing. I have found a lot of people just as confused as me, who then saw in the documentation something to the effect that only one thread can have the upgradable lock at a time. They'd post about it and everybody would just be standing around, scratching their heads. This isn't Boost, but I suppose it describes the behavior: http://home.roadrunner.com/~hinnant/mutexes/locking.html#Upgrade If it's the same mechanism, when multiple shared threads could potentially want to write, they want to wait for all other shared threads to exit first. The fight happens at the upgrade, not at the exclusive portion. At this point, I wonder--what's the point of upgrading to a unique lock when the upgradable lock is already demanding exclusivity? I'm wondering then what I should be doing for my read/write section. It looks like I need to unlock the shared lock before acquiring an exclusive lock--upgradable or unique or whatever. Looking at my code further, I like to lock on STL lists, and I was trying to get a write lock when it came time to erase something from the list. It looks like I need to stop doing that since I'm going to invalidate anybody else iterating through the list at the same time.
|
# ? Apr 25, 2012 15:37 |
|
What's the difference between ++thing and thing++? I have a loop where I want to start iterating at the second item: code:
|
# ? Apr 25, 2012 16:14 |
gggiiimmmppp posted:What's the difference between ++thing and thing++? Pre-increment versus post-increment. ++foo evaluates foo, increments it by one, stores the new value back to foo, then returns the incremented value. foo++ evaluates foo, increments it by one, stores the new value back to foo, then returns the original value. Note that the actual order of the two last parts, "store back" and "return value" is not well-defined. The actual store-back might happen before or after the rest of the statement the increment operator is part of finishes executing. In some cases, pre-increment is faster than post-increment, but never the other way around.
|
|
# ? Apr 25, 2012 16:26 |
|
Rocko Bonaparte posted:If it's the same mechanism, when multiple shared threads could potentially want to write, they want to wait for all other shared threads to exit first. The fight happens at the upgrade, not at the exclusive portion. At this point, I wonder--what's the point of upgrading to a unique lock when the upgradable lock is already demanding exclusivity? The upgradable lock is not exclusive with shared lockers, so you get better concurrency for that time. The analysis you linked discusses why you can't have a shared upgradeable lock — the API implies that the shared lock is continuously held, so if you ever had two simultaneous upgraders, their upgrade operations would necessarily deadlock. What you probably want is to drop the shared lock and then pick up the exclusive lock; by forcing you to do this explicitly, the API makes it clear that you can't rely on any information you gained during the read phase.
|
# ? Apr 25, 2012 18:55 |
|
rjmccall posted:The upgradable lock is not exclusive with shared lockers, so you get better concurrency for that time. The analysis you linked discusses why you can't have a shared upgradeable lock — the API implies that the shared lock is continuously held, so if you ever had two simultaneous upgraders, their upgrade operations would necessarily deadlock. What you probably want is to drop the shared lock and then pick up the exclusive lock; by forcing you to do this explicitly, the API makes it clear that you can't rely on any information you gained during the read phase. Now that I see how this is working, I'm wondering when one would ever actually want an upgrade lock instead of a unique lock.
|
# ? Apr 25, 2012 19:01 |
|
A writer which spends a relatively small amount of time actually writing, but which can't give up the shared lock without invalidating itself. For example, a periodic task to strip dead records from a "database" might queue up its actual deletion work to minimize the amount of time it's forced to exclude readers, but it might not have been written to be safe against intervening writes. Or you might be inserting a record, but you need to link it against a bunch of other records, and finding them is an expensive operation.
|
# ? Apr 25, 2012 19:41 |
|
rjmccall posted:A writer which spends a relatively small amount of time actually writing, but which can't give up the shared lock without invalidating itself. For example, a periodic task to strip dead records from a "database" might queue up its actual deletion work to minimize the amount of time it's forced to exclude readers, but it might not have been written to be safe against intervening writes. Or you might be inserting a record, but you need to link it against a bunch of other records, and finding them is an expensive operation. That's kind of funny because that's in the spirit of what I was trying to do, although I think the activity was too long and regular. I was going through a list of callback listeners, and triggering their event handler if the event I needed to transmit matched what they were listening to. While doing that, I was also checking if there were deleted listeners. If so, I removed them from the list right then and there. So I figured I needed an upgradable lock. I know that using a shared lock for the reads would be dumb because I'd invalidate the list for somebody else while they're in it. The thread that did the cleanup would have the right iterator, but anybody that was inside at the time would have gotten their rear end beat. When I switched it to an upgrade lock, I got deadlocked on the lock when two threads ended up blocking on it. Knowing a little more now about what's going on, I need to check back if somebody else didn't have a shared lock for that block. I assume that would do it. However, I've heard a lot online about two thread deadlocking each other on an upgrade lock. It just doesn't sound right since in my head it sounds like this: 1. Thread #1 has a shared lock on the mutex. 2. Thread #2 wants an upgrade lock on the mutex and blocks. 3. Thread #3 comes along and also wants an upgrade lock on the mutex. 4. Thread #1 releases the shared lock. But somehow #2 and #3 are deadlocked now. Anyways, at some point I started using shared pointers to the callback receivers, so there's no way for them to slip out undetected anymore. So I can effectively scrub that code away and stick to shared locks for most everything. Still I want to know how the heck to actually use these things right.
|
# ? Apr 25, 2012 22:13 |
|
Rocko Bonaparte posted:That's kind of funny because that's in the spirit of what I was trying to do, although I think the activity was too long and regular. I was going through a list of callback listeners, and triggering their event handler if the event I needed to transmit matched what they were listening to. While doing that, I was also checking if there were deleted listeners. If so, I removed them from the list right then and there. So I figured I needed an upgradable lock. It's probably better to remember that you found something and then go back over it with an exclusive lock. I can't see why someone else having a shared lock would cause a deadlock for you. In your hypothetical: Rocko Bonaparte posted:1. Thread #1 has a shared lock on the mutex. Note that you can get a single-thread deadlock if one thread has a shared lock *and* an upgrade lock and then tries to upgrade.
|
# ? Apr 25, 2012 23:35 |
|
I believe what's happening is that the threads are holding shared locks while trying to grab the upgrade lock. One thread is fine, because it can release the shared lock before it tries to upgrade to an exclusive lock, but a second thread still waiting on the upgrade lock will cause the whole thing to deadlock. The way I would think to manage this is by not blocking while waiting for the upgrade lock - instead if you don't get it, just carry on dispatching events and let the thread with the upgrade lock handle deleting stuff. Unfortunately, it seems boost doesn't actually have a try_lock_upgrade() and so the only way to acquire an upgrade lock is to block on it.
|
# ? Apr 26, 2012 00:07 |
|
Short question: If I can "delete this", why can't I assign to this?" i.e. "delete this; this = new Item()". Long question: I've implemented double dispatch with a visitor pattern on an expression tree that contains operators, integers,and identifiers. What I want to do is create a visitor that will simplify the tree as much as possible. My problem is that I need some way of changing a node to a different node while I'm looking at. Otherwise, I'm having to thread a new node back through the visitor pattern to the parent node.
|
# ? Apr 26, 2012 18:21 |
FamDav posted:Short question: The "this" pointer kind-of belongs to the caller, you can't really (directly) change what the caller has. You can assign to *this however. That will call the appropriate operator= for the types. It sounds like you're trying to have the tree nodes themselves know and implement the algorithm to simplify the tree however. I would suggest instead either implementing the algorithm in the tree (and make "a tree" a container of nodes, not just the top node) or as a separate utility function. In both cases you would eliminate the need to "change the identity of this".
|
|
# ? Apr 26, 2012 18:30 |
|
FamDav posted:Short question: this does not name a variable; it's just a keyword which happens to evaluate to a particular pointer value. Since it's a pointer value, you can use with delete, although in many cases that won't work dynamically. Since it's not a variable, you can't assign to it. FamDav posted:I've implemented double dispatch with a visitor pattern on an expression tree that contains operators, integers,and identifiers. What I want to do is create a visitor that will simplify the tree as much as possible. My problem is that I need some way of changing a node to a different node while I'm looking at. Otherwise, I'm having to thread a new node back through the visitor pattern to the parent node. Well, you can't change the identity of a node like this; modifying this would not change all references to it. You can overwrite the memory that's used for an object, but it requires all your nodes to have the same size, and it is incredibly ugly and bug-prone and technically undefined behavior so I'm not going to go into it. There are basically three ways to thread results out of a visitor pattern in C++. The first way is to compute the result directly in the visitor object. This means you'll need to pass copies of the visitor to sub-nodes in many cases, but that's doable. The second way is to template everything; of course, that means that dispatch can't use virtual dispatch, so you'd need some other way to distinguish nodes and cast down. For an AST with a fixed number of node kinds, this is not unreasonable; it may also mean that you can kill vtables completely, which can help space usage if you're making a ton of these. Macro metaprogramming helps a lot. You end up with really ugly files like clang's StmtVisitor but a programming model that's actually not that terrible. The third way is to propagate out some really general type, like void*, and just have the visitor know how to interpret that. rjmccall fucked around with this message at 19:00 on Apr 26, 2012 |
# ? Apr 26, 2012 18:54 |
|
This isn't quite homework, just brushing up on stuff before my intro C++ class starts in a few weeks. The exercise calls for receiving a decimal number input and outputting that number rounded to the nearest integer. This seems to work, but I'm guessing it is kind of inelegant. Might there be a more direct way? code:
|
# ? Apr 27, 2012 00:29 |
|
jhunter46 posted:This isn't quite homework, just brushing up on stuff before my intro C++ class starts in a few weeks. Are you allowed to use ceil() and float()?
|
# ? Apr 27, 2012 00:38 |
|
Arguably your code is very clear and nicely-commented I guess but cout << int(0.5 + inputNumber) << endl; does it in one line and is idiomatic enough that I don't see any reason not to use it.
seiken fucked around with this message at 01:22 on Apr 27, 2012 |
# ? Apr 27, 2012 01:19 |
|
seiken posted:Arguably your code is very clear and nicely-commented I guess but cout << int(0.5 + inputNumber) << endl; does it in one line and is idiomatic enough that I don't see any reason not to use it. Better to use floor(inputNumber + 0.5), and cast that to int afterwards if required. Casting to int rounds towards zero (usually; I think this is actually implementation defined), but you don't want that. -1.4 would round to 0. floor rounds towards negative infinity, which works great.
|
# ? Apr 27, 2012 02:17 |
|
I hadn't seen floor and ceil yet. Thanks.
|
# ? Apr 27, 2012 17:59 |
|
I undertook figuring out how to make a linked list, in C and more correctly how to make functions to manipulate it on my own, not as part of a class. I don't even get to see data structures until the fall at the earliest, but I still want to get my hands on these concepts. http://pastebin.com/6tkkq1sn <- too big to post the entire thing, so here's a link. It compiles and runs without any problems despite me throwing pointers around and mallocing things, though for whatever reason it only manages to add one word to the linked list. If I add another, it just doesn't. As far as I know makeNode (line 42) works fine, so the problem must be in addword (line 59), but I for the life of me can't spot my mistake. I've already asked a few people in industry, and was told summarily to "stop doing this poo poo in C," in favor of C++ or Java, and "no I can't find the bug either." Can anyone tell me what I'm doing wrong?
|
# ? Apr 29, 2012 17:35 |
|
2banks1swap.avi posted:Can anyone tell me what I'm doing wrong? code:
You should either move the "if the node hasn't been added add it now" bit to outside of that loop, or drop the "myP->next != root" from the loop's conditions since inside the loop you check for that and set 'quit' anyway. You could also drop that whole 'quit' malarkey and just return from the function wherever you'd have set quit, since it means "don't do anything else in this function". Edit: actually, what you're doing wrong is not learning to use the debugger, which could have shown you exactly where your code was going wrong pretty effortlessly. Line-stepping through code is the most useful tool of all, it's like a dry-run where you don't even have to think! roomforthetuna fucked around with this message at 17:57 on Apr 29, 2012 |
# ? Apr 29, 2012 17:55 |
|
2banks1swap.avi posted:It compiles and runs without any problems despite me throwing pointers around and mallocing things, though for whatever reason it only manages to add one word to the linked list. If I add another, it just doesn't. As far as I know makeNode (line 42) works fine, so the problem must be in addword (line 59), but I for the life of me can't spot my mistake. I'm just skimming through, but one thing immediately jumps out: In makeNode, you never set temp->prev. I only started to look at "addword" but it's way more complicated than it needs to be and has redundancy. You're also never freeing your memory.
|
# ? Apr 29, 2012 18:06 |
|
roomforthetuna posted:
I do need to get the codeblocks debugger working. If the function is void, how do I return? Can I just pop "return;" as needed? I had a teacher insist that "only one return ever!" (in a given function) which is why you use these variables and &&and statements and such. I guess school-gramming and pro-gramming are two different things.
|
# ? Apr 29, 2012 18:06 |
|
2banks1swap.avi posted:I had a teacher insist that "only one return ever!" Don't listen to that teacher.
|
# ? Apr 29, 2012 18:08 |
|
2banks1swap.avi posted:I do need to get the codeblocks debugger working.
|
# ? Apr 29, 2012 18:10 |
|
roomforthetuna posted:Yes, you can just "return;" as needed. It probably is a little bit technically nicer to only have one return, but if you're going to do that then it should be by the power of 'else' so that you never go near any of the other blocks, not via a "skip other things" bool which I think is much worse, and more error-prone, than just returning mid-function. Got rid of my int quit, made a more readable loop in addword, ran through the debugger step by step, and I'm still absolutely confused. I should add that I started this while running a fever yesterday and I'm still running a less high fever. Otherwise I Can't fathom how I made that big tangled mess called addword();. I also put the temp->prev = myP; into makeNode, thanks turkey story. http://pastebin.com/j2P9FfFa here's my new and less bad code that still has bugs. The debugger had me walk through the part from 81 to 89, but I Can't see anything wrong with addword! Edit: It even went through line by line in makeNode! Fuck them fucked around with this message at 19:13 on Apr 29, 2012 |
# ? Apr 29, 2012 19:06 |
|
check your printwords loop condition vvvvv Why not just code:
Colonel Taint fucked around with this message at 19:40 on Apr 29, 2012 |
# ? Apr 29, 2012 19:13 |
|
SintaxError posted:check your printwords loop condition Thank you very much! Now I have to figure out just how to make this work for my root+1 node list. edit: It either only prints the root or does it for the root twice; it either just says "hurf" or "hurf" then "durf" then "hurf." At least it's funny to watch this pop out. edit v2: code:
Fuck them fucked around with this message at 19:36 on Apr 29, 2012 |
# ? Apr 29, 2012 19:21 |
|
|
# ? Jun 8, 2024 10:55 |
|
What's a good C++ book for someone who's not a completely new programmer? I'm certainly not a good or even experienced programmer but I am having trouble finding a book in that middleground. I'm thinking Horstmann's C++ for Everyone might be a good one, as I like his Big Java quite a bit but I am not totally sure. edit: just realized Big C++ exists too, so I'll probably check that out. etcetera08 fucked around with this message at 20:43 on Apr 29, 2012 |
# ? Apr 29, 2012 20:37 |