doug65536 18 Light Poster

I just realized I should clarify my earlier comments about sleep. I did not mean to imply that you shouldn't call sleep, what I failed to say was, use sleep, but use another way to get how much time actually elapsed, and adapt.

For example: At the start of the loop, get the current "time" (QueryPerformanceCounter is a good way to get it, as LevyDee mentioned). Calculate what the "time" value would be at the end of the delay. Each loop, after the sleep call, check if the next sleep should be less than a second (because the time is almost up) and use that. If you need to wait more than a second more, use a second.

doug65536 18 Light Poster

Yes, that's right.

doug65536 18 Light Poster

Character literals evaluate to the ascii value of the character. scode == 'A' is exactly the same thing as scode == 65.

Boolean expressions are calculations. When you evaluate 2 * 2 == 4, the result is the number 1. When you say 2 * 3 == 4, the result is the number 0.

In C, when it is evaluating boolean (true or false) types of expression (in 'if', 'while', 'for' etc), the whole expression is true if the answer is not zero, and it is false if the answer is zero.

When evaluating scode == ('r' || 'R')) this is the order of operations:

- 'r' || 'R' means the following: if 'r' != 0 then the result is 1, else if 'R' != 0 then the result is 1, else the result is zero

so this is how it would break down:

(scode == ('r' || 'R')
simplifies to (scode == (114 || 82))

when it evaluates 114 || 82, it is essentially a calculation that means, if ((114 is not equal to 0) or (82 is not equal to 0)) then the result is 1, else the result is zero.

114 is not equal to zero, which means it is true. Expressions in C use short-circuit evaluation, so using logical OR, there is no need to evaluate the right hand side, because it is OR, 114 is already true. it can (and WILL) skip the other side of …

doug65536 18 Light Poster

This is a bug that has been reported to Microsoft since visual C++ 4, and has not been fixed yet. Microsoft says it is fixed in VS 2011. We'll see.

doug65536 18 Light Poster

setting up the boolien the way it is now should tell the compiler the same thing as before shouldn't it? its only realy differant synacticaly right?

Not sure what you mean by "the way it is now" but if you mean like gerard4143's comment, yes that works. I simply explained how the compiler interpreted it the way you originally had it, so you'd know why your original code didn't work.

At first knowing other languages is going to bog you down a little, but soon that's going to turn around and make you able to learn new languages even faster. Programming languages are more alike than they are different, and knowing several sharpens your eye to the kinds of issues that you encountered in this post.

doug65536 18 Light Poster

It's the other way around, right? Don't you have requirements that it run on a given operating system, or a requirement that it be portable across a lot of operating systems?

The sockets API is my suggestion. It allows you to have code that is reasonably similar between unix and windows platforms. The big differences there are how to handle asynchronous operations.

Do you mean getting something to work at all, or a highly scalable network program that can handle thousands of simultaneous connections and be bulletproofed so disconnects or corrupt data won't cause program failures. If you need to make it high performance, you will have to do significant work to abstract it enough so you can use the high performance techniques that are specific to each platform.

Security is another big concern, you need to be robust enough to handle malicious data. You need to be robust enough to handle denial of service attacks while still allowing legitimate users to use the service.

You may need to have the ability to configure proxies if the server will be used in commercial environments. You may need to take firewalls into consideration when designing how it is implemented, such as which end of the connection makes the outbound connection.

You may need to choose whether you are going to be firewall friendly and do something "over HTTP", or if you are going to impose a requirement that administrators specifically open ports for it.

You …

doug65536 18 Light Poster

Sounds an awful lot like he wants us to do his homework assignment for him.
Sometimes I feel tempted to post a really sophisticated answer with templates and policy classes and inheritance so it is perfectly clear to the teacher that there's no way he wrote it.

doug65536 18 Light Poster

Mike is talking about industrial strength optimal ways to handle it.

A while ago I developed a very simple way of doing it that is not even close to optimal but isn't too bad:

For triangle A B C calculate the vector

N = crossproduct(normalize(B - A), normalize(C - A))

This will give you the surface normal of the plane, N. Make a plane equation P for the plane:

P = -dotproduct(N, A)

Now we can calculate the distance 'start' is from the plane:

startDist = dotproduct(N, start) + Pd

And we can calculate the distance 'end' is from the plane:

endDist = dot(N, end) + Pd

If startDist is not the same sign as endDist then maybe it goes through the plane. If they are the same sign, the line segment between start and end couldn't possibly go through the plane.

Assuming they are different signs, we need to calculate the actual intersection point. We can do that by taking

intersectFrac = startDist / (endDist - startDist)

to calculate how far along the segment between start end end the intersection of the plane lies.

We can normalize the vector

start + (end - start)

and scalar multiply it by intersectFrac to find the exact point where that line intersects the plane.

We can use the surface normal, and each of the three line segments to generate "extruded edges" for the triangles, making …

doug65536 18 Light Poster

Real encryption algorithms (symmetric ones anyway) are mostly based on an extrememly strong random number generator that can be "seeded", which means made to generate the same sequence of random numbers, given a seed, often called the key.

You take those extremely random numbers and xor them with the data, giving you seemingly completely random output. When decrypting, you use the key again, seed the random number generator with the same seed (key), and do the xor operation again on the encrypted data. Doing an xor again on the encrypted data with the same number will undo the original xor (that you did when encrypting) into the original data.

Is this what you mean?

doug65536 18 Light Poster

What operating system?

doug65536 18 Light Poster

Never heard of "on the fly paging". The closest thing I can think of is "demand paging". It means that things like executable files and dlls are mapped to a range of memory, but it only goes and reads from disk if the program touches those areas of memory that correspond to the file.

http://en.wikipedia.org/wiki/Demand_paging

doug65536 18 Light Poster

What windows is doing when that thing comes up is switching to another desktop. The "other" desktop is heavily secured so that it is very very difficult* for a program to be able to press the button for you (by moving the mouse pointer and clicking it from a malicious program).

* (but not impossible, nothing is truely impossible in a computer, because no software is completely perfect. Even if you did have perfect software, people aren't perfect, they leak passwords, etc)

I would not try to accomplish something like UAC. You could make it simpler and scan for "blacklisted" processes. In C# it's pretty easy to get the list of programs from WMI. You could enumerate win32_process instances and terminate blacklisted programs.

The problem is, you would simply kill the watchdog program, fire up your game and play it anyway. You would need to run your program as a service (to protect it from you disabling it from your limited account), and take away administrative privileges from yourself. You would need someone you trust to enforce your behavior who has admin privileges.

That's one approach anyway. Perhaps you could save the time you spend on this project and simply discipline yourself to work/study.

doug65536 18 Light Poster

I noticed more bugs. You have a constructor with no parameters, and you have one with parameters. Either one or the other will be called. The constructor at line 19 reads the 'next' pointer when nobody has set it yet. It will contain garbage.

doug65536 18 Light Poster

1) Do you need to put new objects at the end? Since you're using a singly linked list, the simplest/fastest way to add an object to the list is to put it at the beginning:

this->next = first;  // The next of my new node points to the one that was first
first = this;        // Now my new node is the first

If you need to put it at the end, then it's more complex, because 'first' might be null because there are no items in the list yet. Here's one approach:

// Keep looping until the next node is not null but also make sure
// endScan isn't null at the beginning
teachersList *endScan;
for (endScan = first; endScan && endScan->next; endScan = endScan->next)
{
     // Do nothing but keep moving endScan to the next node
}
if (!endScan)
{
    // This is the first node, first was null
    first = this;
}
else
{
    // endScan points to the last node
    // point the 'next' pointer of the last node to my new node
    endScan->next = this;
}

2) The pointer to the beginning of the list (I'm calling it 'first' above) needs to be outside the class. Where are you keeping track of the beginning of the list? One approach is to pass a pointer to the 'first' pointer to the constructor. This would involve pointers to pointers, which usually horrifies new C programmers. C++ programmers have it easy with references: Try taking a …

doug65536 18 Light Poster

I think what you are asking is how to reverse engineer the protocol.

Yes, reverse engineering is usually difficult.

One approach is to make the program do known things and watch the data. Repeat the operation and see what changes and what doesn't. Then do something slightly different and see what changes. You will gradually figure out the structure of the data by comparing the data packets to your input. You can gradually narrow down the layout of the packets.

doug65536 18 Light Poster

It might be logical, it might be physical. Depends on the hardware and how it is configured. If the processor has no memory remapping capability (i.e. no MMU) then you ONLY have physical addresses. Ancient home computers (before 80286) had no MMU (memory management unit). The first commonly used desktop computer that had a good MMU was the 80386. Even on an 80386, addresses might be logical or physical depending on whether you enabled "paging" (enabled the MMU). Even with paging enabled, if your page tables mapped the logical addresses to the same physical address, pointers would be both logical and physical (there would be no distinction). If your page tables mapped memory in such a way that logical addresses don't map to the same physical address, then there would be a difference.

For example, if you were writing a driver for a piece of hardware, you would need an awareness of physical addresses. Your piece of hardware might have some memory that can be mapped so it is accessible by the CPU. Say you knew somehow that the memory is mapped to physical address X. In a typical operating system, you could make a system call to request access to that physical address. The operating system would map some range of logical addresses to that physical addresses. In your driver code, you would have a pointer to the logical address, and the MMU hardware would map it to the physical address expected by the hardware.

I suppose …

doug65536 18 Light Poster

Study operator precedence. I know it's boring as hell, think of it as the same kind of thing as learning your times tables -> boring as hell but great to know once you know. It helps a lot to be able to look at an expression and know what order it will be evaluated in.

What it was doing before was evaluating scode == "p" first. If that was true, the whole expression is true because it's logical or (look up short-circuit evaluation).

If scode is not equal to "p", then it evaluated whether "P" is true, which it always is, because "P" is not a null pointer. A literal string evaluates to the pointer to the first character of the string. Therefore the if condition is always true.

doug65536 18 Light Poster

The 'if' statement on line 16 only affects the cout << q. If you look carefully, you'll see that the 'break' is always executed and it will never loop.

However, it's still wrong if you fix that. From what I can tell by running the code in my head, you are attempting to convert the entered number to base 2. Your code will put the least significant digits first, which is backward. For example, if it were base 10 (if you replaced the '2' with '10'), then the number 264 would print

4
6
2

You need to reverse the order of the digits for it to be a proper binary number.
Why not do the endl outside the loop, after it has completed?

Why is it looping while q is not equal to 1? Can you describe why it shouldn't be looping while it is not equal to zero? Your program should print '1' if you enter 1, right?

doug65536 18 Light Poster

There is a lot more to it than blindly copying a block of code and expecting it to work. It depends very much on the processor and the instructions being used. For example, a switch statement might have a lookup table somewhere else. It might be using jump vectors for dynamic link library imports that won't necessarily be there. It might have string literals that it is expecting to be at a certain address in the const section. It might be referring to global variables that may not be there or may not be at the expected address.

The worst problem is there might be instructions that use absolute addresses - which will be wrong if you put it at a different address. It might call other functions, how will they work? How will it know what address those are at (assuming they exist at all).

Ancient Dragon commented: good :) +17
doug65536 18 Light Poster

You can't rely on Sleep to reliably sleep for one second. If you read the documentation for sleep, it will specifically say that it might (and in reality, often will) sleep for more than the specified time period. If the cpu is under load (like if there are processing intensive processes contending for processor time) Sleep will be very inaccurate.

doug65536 18 Light Poster

As far as I can tell from the documentation, doing WaitForThreadpoolWaitCallbacks will do the same thing as the cleanup group (the cleanup group is also a "container" for several threadpool objects - tied together by the threadpoolenvironment, automating waiting for all the callbacks, etc, and closing them all).

The documentation even mentions an exception is possible if you set a wait concurrently with the cleanup. That is what is going to happen, because the wait callback has to setup the next wait every time, it's going to be setting a new wait every time it fires to get the next waited-for event.

The issue is, because the new wait must be continually reissued every time the wait fires (from the wait callback), it creates a race between code that is trying to stop the wait callbacks and the code in the callback that is trying to setup the next wait.

doug65536 18 Light Poster

Exactly, which is why I said "if you miraculously knew that it was member 'b' in Func"...

The problem given is impossible because:
1) The struct is unnamed
2) We can't assume that it's the Check instance of the structure. If we could then we can ignore *p and just say &Check is the base!
3) From a raw address it is impossible to determine a struct offset without knowing what member it is.
4) Without an offset, calculating the base is impossible.

Double check that you have posted the actual problem correctly.

doug65536 18 Light Poster

If you know the name of the *member* of the structure and you know the type of the structure, you can use offsetof(type,member) and do some pointer arithmetic.

It is impossible to get the base of the structure in C (or C++) without knowing what member it is and what type it is.

You must be mistaken that that is the "exact" problem given to you. The structure is unnamed, and you don't know what member *ptr is pointing to.

Please double check that you have posted the exact problem. The answer to the current assignment given is, "it's impossible".

MAYBE you can cheat and use decltype(Check) to get the type of the unnamed type (never tried to do something silly like that, not sure it works). Then if you miraculously knew that it was member 'b' in Func, then you could use:

void Func(void *p)
{
    typedef decltype(Check) StructType;
    size_t memberofs = offsetof(StructType,b);
    void *base = (void*)((char*)p - memberofs);
    cout << "The base address is " << base;
}

If you're cheating that much you might as well just say &Check is the base address.

doug65536 18 Light Poster

As a workaround, I am using a slim reader writer lock and doing a TryAcquireSRWLockShared. If it acquires the lock, I proceed to test the shutdown flag etc. Before shutting down, I acquire exclusive lock and set the shuttingDown flag. If the threadpool callback is racing the shared acquire will lockout the shutdown code until the callback returns. If the shutdown gets the exclusive lock first, the racing thread will fail to TryAcquireSRWLockShared.

Any ideas how to avoid the SRW lock though?

doug65536 18 Light Poster

I have a project that uses DirectSound to play streaming sound.
I use SetThreadpoolWait to get a threadpool callback every time the notification (AutoReset) events are signalled. (To fill the streaming buffer with more audio).

The new Win7 threadpool API requires you to use SetThreadpoolWait to schedule a new wait every time it issues the callback - you need to reschedule a new wait every time it fires a callback.

Here is the class that I wrote to wrap the threadpool wait:

template<>
class ThreadpoolWaitImpl<true>
{
	AutoCloseThreadpoolWait wait;
	void *callbackTarget;
	HANDLE handle;
	FILETIME timeout;
	bool onlyOnce;
	bool shuttingDown;

public:
	typedef ThreadpoolWaitImpl<true> Wait;

	ThreadpoolWaitImpl()
		: callbackTarget(0)
		, handle(0)
		, onlyOnce(false)
		, shuttingDown(false)
	{
	}

	~ThreadpoolWaitImpl()
	{
		shuttingDown = true;
	}

	template<typename T, void (T::*func)(const Wait &, BOOLEAN)>
	BOOL SetWaitCallback(T *target, HANDLE waitObject, 
			ULONG milliseconds = INFINITE,
			ULONG flags = WT_EXECUTEDEFAULT)
	{
		callbackTarget = target;
		handle = waitObject;
		onlyOnce = !!(flags & WT_EXECUTEONLYONCE);

		wait = CreateThreadpoolWait(
				ThreadpoolWaitImpl<true>::TimerCallback_C<T, func>,
				this, NULL);
		if (!wait.IsValid())
			return FALSE;

		if (milliseconds == INFINITE)
		{
			SetThreadpoolWait(wait, waitObject, NULL);
		}
		else
		{
			LARGE_INTEGER timeoutUnion;
			timeoutUnion.QuadPart = milliseconds * 10000000;
			timeout.dwLowDateTime = timeoutUnion.LowPart;
			timeout.dwHighDateTime = timeoutUnion.HighPart;
			SetThreadpoolWait(wait, waitObject, &timeout);
		}
		return TRUE;
	}

	template<typename T, void (T::*func)(const Wait &, BOOLEAN)>
	static VOID CALLBACK TimerCallback_C(
			__inout     PTP_CALLBACK_INSTANCE instance,
			__inout_opt PVOID                 context,
			__inout     PTP_WAIT              wait,
			__in        TP_WAIT_RESULT        waitResult)
	{
		auto self = reinterpret_cast<Wait*>(context);
		auto target = reinterpret_cast<T*>(self->callbackTarget);
		(target->*func)(*self, waitResult == WAIT_OBJECT_0);
		if (!self->onlyOnce && !self->shuttingDown)
			SetThreadpoolWait(self->wait, self->handle, &self->timeout);
	}
};

AutoCloseThreadpoolWait is a RAII object that automates safely …

doug65536 18 Light Poster

How do YOU think you would do it. Are you looking for someone to outright do your homework for you?

I see absolutely no effort on your part. Did you even try to do it? Did you write any code?

If you post code and perhaps show that you even attempted it, you will probably get much more help than blindly giving your assignment to everyone to do for you.

doug65536 18 Light Poster

There's nothing wrong with typedef double T. What is wrong with it? Does it HAVE to be a template argument? No! I am siding with the professor on this one. If you are typedef'ing inside a class scope, then doing typedef double T is perfectly fine - it enables you to change the whole class to use 'double' (or some other type) by making a change in one place.

Even if you made a global declaration of typedef double T, it would be FINE! If you made a template<typename T> then the typedef would go out of scope, and there would be no problem. Would it be a best practice? No. But it wouldn't be so utterly wrong and stupid as you implied.

Mike, I don't see why you see fit to disrespect this student's teacher.

doug65536 18 Light Poster

I have a suggestion to get better randomness from rand().

The high bits are the most random, the low bits are a lot less random. If you use modulus, you are effectively using the low bits - your random numbers won't be very random.

To get optimal randomness from rand(), you should use the high bits.

rand() returns a value between 0 and RAND_MAX. My suggestion is to use the following:

int randomNumber = rand() * range / RAND_MAX;

where randomNumber is the random number (obviously), range is the highest value you want (in your code, it's 1) and RAND_MAX is a constant defined in the standard library header file.

You might run into trouble if you are using a large number for 'range'. Since C99 defines rand() as returning an int, you can guarantee correct behavior by making the expression a little more robust:

int randomNumber = (int)(((long long)rand() * range + (RAND_MAX / 2)) / RAND_MAX);

Almost everybody uses rand() wrong. Your lessons probably are teaching you to use it wrong too. When the randomness is important, remember, use the high bits from rand(), not the low bits.

doug65536 18 Light Poster

For these kinds of problems, keep a toolbox of ways of thinking of the numbers in your mind. The trick that applies here is remembering that dividing by a lower number will give a higher result. 5/1 = 5, 5/0.5 = 10, 5/0.25 = 20, etc...

So if you have the number of bytes transferred in one variable, and the amount of time that has elapsed in another, then transferred/elapsed = the number of bytes transferred per unit of elapsed. If transferred is in bytes, and elapsed is in seconds, then the result would be bytes per second. Since we know that there are 8 bits in a byte, then transferred * 8 / elapsed would give bits per second. Since we want MEGA bits per second, we need to divide the result by 1000000. It's pretty much basic algebra to perform further transformations.

There's a bit more to it if you are not using floating point. Remember that if you want to divide it by 1000000, then you wouldn't want to do the divide on the left hand side - because it might make it a number so small that an integer would be zero. So in that case, you can do the opposite thing on the other side of the division operation. If you did (bytes * 8) / (elapsed * 1000000), then your answer would be in megabits per second, and it would work if they were integers. The other option would be to do …

doug65536 18 Light Poster

At the start of the fight, C would open up with a flurry of super high speed punches. After a while though, the C program would start to bog down, because the developer used simplistic algorithms - lots of linear searches and the like.

C++ would maintain higher damage later in the fight, due to having lots of O(log(n)) performance containers. Therefore, C++ would win ;)

doug65536 18 Light Poster

I didn't see anything saying that the OP was asking to prove that 0.999<repeating> was equal to 1.0. The OP says, prove that 0.999 (which I interpreted as exactly 0.999 as in 0.999000).

Is this a sinister puzzle given by a computer science teacher or something? If so, I believe I see the trick to it.

The puzzle probably wants you to realize that floating point numbers are typically stored with a mantissa and an exponent. What I believe the puzzle is looking for is you to come up with a floating point representation format where the mantissa doesn't have enough bits to store 0.999 - the closest representation would be 1.0.

Eagletalon commented: Good logic and well writeen answer with a start to solving it +1
doug65536 18 Light Poster

I did some quick web searches for "allegro page flipping" and found a page that shows how to do page flipping.

For smooth animation of this sort, you can't just draw and hope for the best. You need two copies of the screen. The 'front' buffer is the one the user sees. The 'back' buffer is the buffer where you do the drawing.

See http://wiki.allegro.cc/index.php?title=Page_flipping

1) create the two video bitmap objects
2) show one of them
3) keep track of which one you are not showing that is usable instead of 'screen' when drawing, perhaps a global variable back_buffer.
4) make a function that "page flips" by showing the one you've been drawing to, and changing back_buffer to point to the "other" video bitmap.

This is how real renderers (i.e. games) do animation.

doug65536 18 Light Poster

Not sure how you plan to write a program to prove that, since you already know it's false.