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
Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If the function expects that it needs to free the array you passed it in some cases, then very bad things can happen.

Otherwise, if it expects a pointer to a section of memory with some values, and you give it a pointer to a section of memory with some values, it shouldn't care that there are other values immediately preceding the one you pointed it to.

Adbot
ADBOT LOVES YOU

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Dooey posted:

code:
std::vector<int> vec = some_func_returning_a_vector();
for (int i = 0; i < vec.size(); ++i) {
    if (some_condition) {
        vec.erase(vec.begin() + i);
        --i;
    }
}
Is this the proper way to loop through a vector (or any container really) and remove the items that match some condition?

No specific C++ experience, but I'm going to go with "no", at least as far as a C++ vector goes. Taking elements out of the middle of a vector requires copying all of the following elements. If you're going to be removing a significant proportion of the elements, you're probably better off copying all of the ones you want to keep to a new vector instead.

Even when dealing with a linked-list type structure such as a deque, you should be using an iterator to traverse the list and remove the elements.

Jabor fucked around with this message at 10:20 on Sep 19, 2010

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

shrughes posted:

Just a heads up, a deque is not necessarily a linked list.

As I mentioned, I'm not a C++ guy. Checking the docs again, this is correct. Replace "deque" in my post above with a suitable collection-that-supports-efficient-removals-from-the-middle.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Why are you implementing rotation by using reversals? That seems unnecessarily complex and error-prone for what is actually a pretty simple operation.

Anyway, a rotation by one is trivial to implement by grabbing the bit that will be shifted off the end, moving every other element by one, and then sticking the "stored" bit back on the other end.

A naive implementation will then repeatedly shift-by-one to get the result - it's slow and easily-improved, yes, but the point is that it works, which means that you can use it to easily test your current implementation to see if it's giving correct results. Once you can easily test whether it gives correct results, it's going to much easier to find any bugs.

Also, why are you using that silly xor-swapping technique when you can simply call "set" with the opposite arguments instead?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

A MIRACLE posted:

I'm finishing a lab for data structures and I'm getting this warning:

whenever I pass a 2-d char array like this:

code:
strcpy(rowArray[i][j], tempStr);
Is there a quick fix for this?

If you're looking for a "quick fix" instead of trying to understand what's going wrong, you're looking at this problem the wrong way.

First of all, what are you trying to do? I'm guessing it's not "make a copy of a string".

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You could go the way Chrome does it and encapsulate each plugin in its own process. That way there's no chance of a crashing plugin going and scribbling over some important data needed by the server itself.

Though you'll need to keep in mind that a crashing plugin could still be sending erroneous data to the core, but there's really no way to avoid that except for writing the plugins so they don't crash in the first place.

The alternative to full memory-space isolation is to use something "safe" like Lua, which will guarantee that even if the plugin fails, it won't wreck anything outside of its own state.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If all your plugins are going to be doing is parsing result data and determine what persistent-state updates are needed, then it really sounds like the best solution would be to just chuck a small scripting language in there and use that.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I guess I might just be underestimating how complex your persistence is, but surely it shouldn't be too complex to implement a comprehensive interface?

I mean, what possible outcomes are there from a game? The user gained/lost {x} in-game currency? The user found {x}, {y} and {z} items? The user's rank changed by {x} points?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

roomforthetuna posted:

Some of which may have characteristics that don't already exist, so now the interface needs to already have had a way of adding items that I didn't think of with characteristics that I didn't think of ...
This isn't necessary unless you're going so far as to be generating new, unique items while the game is running. If you're just adding previously-unthought-of items when you add a new plugin or update one, this can be handled by manually updating the items database when you do that.

quote:

Other things a game's scoring might want to do - refer to scores from other related games, access data about a guild/team of some sort, check how much you've played recently, assign achievements.
Achievements are something "obvious" the API should handle, everything else can all be handled by giving plugin processes read access on the backend. Not everything needs to go through the core server.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

roomforthetuna posted:

I'm going to be adding a new plugin or updating one while the game is running!
Yep, and you can manually update the database when you do that. The only case in which you wouldn't be able to do that is if the plugins themselves generated arbitrary unique items on their own.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
It should work unless you're one some platform where uint is 16 bits. Or the platform is little-endian in the first place and you don't need to convert. If you don't need to worry about those situations, then you can do it a whole lot simpler:

code:
uint32_t SwapEndianness(uint32_t src) {
  return ((src & 0xFF) << 24) | ((src & 0xFF00) << 8) | 
         ((src & 0xFF0000) >> 8) | ((src & 0xFF000000) >> 24); 
}
And then I guess you could implement UIntFromChar as

code:
uint32_t UIntFromChar(char *buf) {
  return SwapEndianness(*(uint32_t *)buf);
}
Maybe even stick a few #ifdefs in there to handle the platform-endianness issue.

Jabor fucked around with this message at 10:33 on Nov 25, 2010

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Zaxxon posted:

I guess I need to use a data structure like List or something which doesn't have to reallocate or do some other kind of thing to make the vectors safe.

The solution is to use some form of synchronization to ensure that nothing else is trying to read the vector while it's being modified.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

FlyingDodo posted:

Say I have a tree and I want to be able to get something from the tree by getting a pointer/reference to an object in it, not a copy. Is there a way to prevent the objects from being modified? I know I could use a const pointer or reference but its still possible to cast it as a plain old pointer and then change the data the pointer is pointing at. This is bad because the object would no longer make sense in the place it is in the tree.

Is there someway to prevent this?

If you can't assume that the code you're handing the pointer off to is going to respect constness, then your tree getting messed up is not the problem you should be addressing.

If you're writing an application, then you shouldn't be running untrusted and potentially malicious code with full privileges to mess about in your address space.

If you're writing a library, then if the user of your library doesn't respect your preconditions, your library no longer needs to guarantee any sort of "correct" behaviour.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Zaxxon posted:

Well the reason I think a list would be a good Idea is as follows. The audio thread exists as a callback which gets called at a specific rate, it's a function of hardware. If I simply lock the vector I will hear a gap in the sound until the audio is resumed.

If I use a list I can tack a new pokey onto the end and the ones that are already there won't be lost. I will just have 2 instead of 3 until the 3rd is ready.

Seriously now, how fast are you planning on calling this? Adding an object to a vector is a fast operation, simply adding locking around that won't break your callback.

The only time you could potentially notice it is if a large reallocation happens and a lot of copying needs to be done. And you can get around that by reserving a large enough space up-front.

Note that reserving space up-front without adding locking doesn't actually solve your problem. Sure, it might deal with the most common symptom of your lack of thread-safety, but there's no guarantee that you've actually resolved the issue.

If you want a concurrent data structure, use a concurrent data structure instead of one that just seems concurrent when you test it. Grab, say, Intel's "Threading Building Blocks" library and use a Concurrent Vector or something.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Zaxxon posted:

The only reason I used a vector in the first place is because it felt like the simplest STL data structure I could iterate through. I don't really need any of the other properties of vectors, I don't require random access at all. A list really just makes as much sense, and if I find thread safety problems I can always add locking to the list addition.

Don't put off dealing with concurrency issues until they actually show up - if you think everything's all fine but there's a race condition hidden in there, you can bet it will show up after you make some minor change elsewhere and be a complete bitch to track down and resolve.

There are plenty of concurrency libraries out there. If your design calls for multiple threads you need to have that in mind from the start rather than trying to hack on things to fix them when they break.

It costs you nothing to use new concurrent_list instead of new list, whereas it's potentially a lot of time saved debugging random threading issues.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Zaxxon posted:

I'm not really sure what normal concurrency stuff would work in this situation.

Just use a concurrent collection instead of a regular one. If you're in a position to consider replacing a vector with a list, you're also capable of replacing it with a concurrent list.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

shrughes posted:

The problem with attacking concurrency in programming languages is that it only works if the entire system is written in that programming language, and if the entire system stays within one computer.

Not if we shift towards languages targeting distributed computing.

quote:

The thing is, if we look for programming languages that are good at concurrency, we find that the reason is in their VMs, not in their language.

If we arbitrarily limit ourselves to imperative languages then I guess so, but if we're willing to step outside that, there's a whole lot of auto-parallelization that can be done with things like logic programming that just isn't feasible with a purely imperative language.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You haven't actually given the struct itself a name. You've created an anonymous struct, and then typedef'd it as Book. There is no such thing as a struct Book.

If you want to use just struct Book to refer to a struct, define it as:

code:
struct Book
{ //...
}
If you want to just use Book (no struct) do it as so:

code:
typedef struct
{ //...
} Book;
If you want to use both, then:

code:
typedef struct Book
{ //...
} Book;

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

TasteMyHouse posted:

Also what does nn=5,k mean?

If I rewrote it like so, would it help?

code:
int k,nn=5;

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

TasteMyHouse posted:

no, I know that that is valid C/C++ and what it means. I just don't understand what function he thought it was fulfilling as part of his example.

It looks to me like "I'm not entirely sure what is/isn't related, I'll copy-paste the whole code up to that point so I don't leave out any crucial detail".

Unless the question was rhetorical?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

darkhand posted:

Yeah I'm trying to wrap my head around implementing Remove(int index) but at some point the caller has to know the index of the Student. So Vector could have a T Get(int index) that returns the object at index in the list. And the caller can figure out if it's the right Student or not?

Doing it this way (caller iterates over the list to find the right one, then removes it) is feasible, yes.

But doing it the specific way you describe (through a random-access get method rather than an iterator) isn't very nice, particularly for a linked list implementation.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

brosmike posted:

(I have no idea how C# does it)

C# is a mix of both, really. It emits a different implementation every time you instantiate it with a value type, but uses a single implementation for all reference types you use it with.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Did you try running the computation multiple times before you added that snippet?

Have you tried running it under a debugger and looking at the memory yourself rather than printing it out?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Innocent Bystander posted:

Since this is in the middle of 5k+ line ecosystem, I'm having trouble unit testing this. Is this a satisfactory fix? Or am I missing the point entirely.

Well, let's take a look at it.

code:
int nleft, nread;
  char* ptr2;           ///Declared char*
  nleft = nbytes;
  while (nleft > 0) {
      nread = read(fd, ptr2, nleft);
What is going to happen on that last line?

Also:

code:
  ptr = ptr2;          ///ADDED ASSIGNMENT of ptr2 to ptr
  return (nbytes - nleft);
What is that assignment-immediately-before-return going to achieve?


Innocent Bystander posted:

As I look at the code though, and the rest of the code base, I just wonder why it was implemented like that in the first place? Was there a particular mindset in the early 2000s or something?

The contract of read is that it reads at least some data, but isn't required to read the entire requested amount. There are good reasons for this (what if you're reading over a slow-rear end network link, but have the first bit cached on your end? What if you're reading from a pipe and there is no more data yet?), but for situations where you know the data is there and you know you're going to want it all, a convenience wrapper like this is very useful.

Jabor fucked around with this message at 08:59 on Jun 3, 2011

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
"Pretty much" comment out all the code?

What happens if you change main to this?:

code:
int main() {
	//read(); 
	//display();
	//process();
	return 0;
}
And then what happens if you uncomment those functions one at a time?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Haven't touched OpenCV in a little while, I think you want something like:

code:
m_projectedTrainFaceMat->at<float>(iTrain * m_nEigens + i)
Or perhaps

code:
m_projectedTrainFaceMat->at<float>(iTrain, i)
if m_nEigens is the number of columns and it's set up correctly.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
He's actually talking about the initializer list on the constructor itself. The relevant line in the example:

code:
Bear(BearKind kind) : Animal(getColoringForKind(kind), 4), _kind(kind) {
Note how the Bear(BearKind) constructor is passing getColoringForKind(kind) through to the Animal constructor - you're going to want to do something similar with passing the fee through.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

nielsm posted:

I believe some of the lower levels in the kernel does, but if that applied to you you'd probably already know :)

Also the command shell does - just try running debug/something.exe.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Well first of all you should actually indent stuff.

This is terrible:
code:
if (head2!=0) {
while (head2->next!=0)
{head2=head2->next;}
obj *newobj = new obj(a,b,type);
newobj->next=0;
newobj->prev=head2;
head2->next=newobj;
return 1;
} 
else {
obj *newobj = new obj(a,b,type);
newobj->next=0;
newobj->prev=0;
head=newobj;
return 1;
}
I mean look at it. You can't make head nor tail of how control flows through that mess, or anything else. The whole point of structured programming is to give stuff structure.

Like this:
code:
if (head2!=0) {
   while (head2->next!=0)
      head2=head2->next;

   obj *newobj = new obj(a,b,type);
   newobj->next=0;
   newobj->prev=head2;
   head2->next=newobj;
   return 1;

} else {
   obj *newobj = new obj(a,b,type);
   newobj->next=0;
   newobj->prev=0;
   head=newobj;
   return 1;
}
The code is semantically identical. But the structure is much more apparent.

Secondly, why do you even need an obj_create? Why isn't the obj constructor sufficient?

Jabor fucked around with this message at 09:08 on Aug 22, 2011

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If you're confused about something, the best thing to do is actually write some code and play around with it to figure out how it works.

So start by modifying the loop a little:

code:
while (in_1 >> ws && !in_1.eof() ){
             in_1 >> str;
             cout << "ws=" << ws << ", str=" << str << endl;
Run that, see what happens.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You could look at how the Java Scanner class handles a similar problem:

1. hasNextFoo() tells you if the next record is of a particular type
2. nextFoo() returns the next record if it is of a particular type, and fails otherwise.

If you're having to do significant logic based on whether the next record is a line, a point, or whatever, then this seems like a reasonable solution.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Good Will Punting posted:

I understand recursion from math classes, but wow, the way it was explained in my class through Towers of Hanoi was piss poor. I've heard Stack Overflow suggested here, but is there anywhere less, specific I guess?, for me to continue my studies after this class is over? I don't really know where to go from here, I guess. The resources in the OP look a little advanced for where I'm at.

My best suggestion would be "Don't think you're somehow constrained to C or C++".

Learn Scheme or Haskell or F# or something if you really want to force yourself to grok recursion.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If all the code samples you get given look like that, perhaps you should inform whoever writes them that it's not 1980 any more and we have screens larger than 80x24 characters, so they're actually allowed to use whitespace and indentation.

Here it is formatted a little cleaner, with better comments:

code:
#include <iostream>
using namespace std;

void moveHanoi(int n, char from, char to, char spare) {  
  if (n == 1) {
    //If we're only moving one disk, then we can just move it.
    cout << "Move disk from " << from << " to " << to << endl;

  } else {
    //Otherwise, we need to move all the smaller disks to the spare peg
    moveHanoi(n-1, from, spare, to);

    //Then we need to move the disk we're interested in
    cout << "Move disk from " << from << " to " << to << endl;

    //And finally move the rest of the stack back on top of it.
    moveHanoi(n-1, spare, to, from);
  }
}

void main() {
  int numberOfRings;
  const char PEG_A = ’A’, PEG_B = ’B’, PEG_C = ’C’;

  cout << "This program solves the Towers of Hanoi problem" << endl;
  cout << "Enter the number of disks: ";
  cin >> numberOfRings;
  
  moveHanoi(numberOfRings, PEG_A, PEG_C, PEG_B);
}

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
"Dependencies" = stuff I depend on, "Dependents" = stuff that depends on me.

The latter isn't used all that often because you usually don't know what third-party stuff other developers have created that depends on something you've written, while the set of your dependencies is pretty static.

For example, using your package manager to install gcc + dependencies will install libc etc., but won't install gnuprolog and anything else that in turn depends on gcc. Because that would be a silly operation to want to perform.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
So what you're attempting to match is:

1. An open-<
2. Any characters as long as they aren't >
3. A non-printable character
4. Some more any-characters-that-aren't >
5. A close->

The regex you've got (with some liberties taken for whitespace):

code:
\<
[^>[:print:]]*
[^[:print:]]
[^>]*
\>
Hopefully this helps make stuff more apparent.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

roomforthetuna posted:

Which is to say, I think
\<[^>]*[^[:print:]][^>]*\>
would work if all you need to do is detect that there is a non-printable in a tag.

Sorry, I had to catch some sleep, but yeah this is basically what I was getting at.

In my breakdown of the problem, parts 2 and 4 were identical - and I broke down the regex to try in show that in your solution, you had two different things for those parts.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
C doesn't keep track of array dimensions automatically, you need to do that yourself.

I think you'll find that sizeof() is giving you the pointer size (because that's what it knows about at compile-time), which is unrelated to the number of elements in the array.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

GrumpyDoctor posted:

hurrrr :rolleye: I should probably stop working on this for today.


What?

Suppose you've got some datatype:

code:
struct fart {
    [...]
    char *butts;
}
And suppose you have some code that cleans up that datatype:

code:
void cleanUp(fart_t *f) {
    [...]
    free(f->butts);
}
Now suppose that code gets passed a pointer to some uninitialized (read: "could be anything") memory.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
So this just popped up, and I figured this thread might find it interesting.

The first three are easy, of course, but the last one threw me.

Adbot
ADBOT LOVES YOU

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Rocko Bonaparte posted:

I have some threads looping on their own bools. When they go false, I exit the thread. I think sometimes this isn't working. What I've seen in the long past last time I dealt with this was that the value was getting cached, so one thread's true was another thread's false. What is there in boost's own stuff to eliminate this kind of problem. I assume there's something more robust than just declaring all the relevant stuff volatile, and I don't think mutexes are going to protect me from that. Wouldn't a mutex just ensure at one time only one thread is touching a representation of the variable?

Volatile may or may not be what you're looking for. What you need to understand is what volatile guarantees, and what it doesn't guarantee.

Declaring a variable as volatile essentially means that all reads and writes to it actually go and touch that storage location, and it's guaranteed that those accesses won't be optimized away. It's also guaranteed that accesses to volatile variables won't be reordered with respect to each other.

What volatile doesn't guarantee is ordering with respect to non-volatile accesses. In the common multithreading scenario, your shared data isn't volatile (because that's a significant performance hit in a lot of cases), but you're using some other variable to synchronize access. In that case, volatile isn't enough, because the compiler is allowed to move the access to shared data on to the wrong side of the volatile access.

In your specific scenario, volatile may be sufficient, depending on what you're actually doing in these threads.

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