thelamb 163 Posting Pro in Training

There is nothing wrong with this snippet (but yes, use dynamic_cast).
Maybe you set the breakpoint wrong, You're saying something with a DLL and an EXE, so if the code of Main() is in the DLL, how did you set the breakpoint?

You can try instead to show a MessageBox.

thelamb 163 Posting Pro in Training

listen (basically) just tells the OS that you will be listening for new connections on this socket. It should only be called once, for each socket you want to listen on.

select-like functions tell you when there are new connections on a socket that you are listening on. You can have select behave differently by setting socket options like blocking or non-blocking. These things are documented extensively so just google a bit for when select is used, and how you can use it in your program.

thelamb 163 Posting Pro in Training

Naturally, you can have multiple connections to one port. Just think of an HTTP web server serving web pages to thousands of users connected on port 80.
The way you distinguish between clients is by socket number.

Now, you falsely assume that every time accept (or any WinSock functions) returns error, it is a fatal error.
Take a look at the documentation:
http://msdn.microsoft.com/en-us/library/ms737526(v=vs.85).aspx

You should be checking for 'INVALID_SOCKET', and then calling WsaGetLastError to get a more detailed error code. Some of these error codes are not fatal, like EWSAWOULDBLOCK.

Next, you should not blindly call accept. There are nice ways to determine whether there is a new connection pending or new data in the buffer, ready to be received. Look at functions like 'select'. I know that on Linux there are better alternatives than select, I forgot if this is the case on Windows. In any case, select will do fine for a first try.

thelamb 163 Posting Pro in Training

There is a big OS development community here:
http://forum.osdev.org/index.php with a wiki: http://wiki.osdev.org/Main_Page

Usually, hobby-OS projects are compiled with a GCC cross compiler. There is a document on the OSDev WIKI about how to set this up. In early stages, the kernel can not depend on anything from from libc - so a stripped down compiler is necessary.

While it is possible to write an OS is assembly, it is hardly ever done any more.
I'm not really sure what your question about inline-asm in C with regard to Windows/Linux is, but:
If you will ever write a Windows kernel driver, you _can_ use inline asm but it is _highly_ discouraged. Mainly because the ASM is platform dependent, and very very easily breaks on someone else's machine.
That is why only minor parts of an OS are written in ASM.

The book for 32bit asm will do fine, as you will probably write a 32 bit OS (don't start with a 64 bit kernel).

You don't need to burn the OS to a CD every time you test it, there are virual machines like Qemu, Bochs etc.
You will 'just' compile your kernel, stick in the boot loader, and tell one of these virtual machines to load it as if it were a floppy disk.

thelamb 163 Posting Pro in Training

When you pass an array to a function, information about its size is lost (unless the function only takes arrays of a certain size, e.g. void foo( string arr[100] ); instead of void foo( string* arr ) or void foo string[] arr) ).

Since this is a C++ forum, you're much better off using std::array or std::vector (or any other container that suits you needs, which is most likely std::vector).
So the following works fine:

void foo( const vector<string>& bar ) {
   cout << bar.size() << '\n';
}

int main() {
    vector<string> myVec;
    for( int i = 0; i < 100; ++i )
        myVec.push_back( "Hello" );
    foo( myVec );
}
thelamb 163 Posting Pro in Training

You can use (win)pcap to gather network data... it's probably a bit over-kill for your solution though.

If you're doing this on Linux, why not make use of /dev/random?
On Windows, why not use 'CryptGenRandom()'?

If you somehow don't want this, I think easier randomness can be obtained from mouse position/time between keystrokes etc. I believe this is even what Linux does, but don't pin me down on that.

thelamb 163 Posting Pro in Training

So, do you understand why? That there is no return statement, so how should it know what to return?

thelamb 163 Posting Pro in Training

How about instead we help you solve what is wrong with this code.
Now, to do that.. we need to know what you mean with 'doesn't work when called'. This sentence alone is not very helpful:
Does it crash? Does it just it give output, but not what you expect? Does it give no output at all?

My guess is that latter. Why? Because there is no return statement in the timestamp() function. You should set the warning level of your compiler higher, I have never used devc++ though.

thelamb 163 Posting Pro in Training

How about:

bar = foo[3];

?

thelamb 163 Posting Pro in Training

I'm not sure if this is what you mean, if not, can you give an example what you're confused about?

struct base {
   virtual void test() {}
};

struct derived : public base {
   void test() { }
   virtual void test2() { }
};

int main() {
   derived* d = new derived;
   base* b    = (base*)(d);

   b->test2(); // compile error, test2 is not a member of base
   d->test2(); // Fine, 'd' has a vptr which includes test2

   b->test(); // calls derived::test, even though b is d, casted to base*, it still points to a derived object in memory
}

derived 'adds' a new virtual function, 'test2'.
It's not like both base and derived share the same vptr, they are two distinct classes who happen to share a common interface.

thelamb 163 Posting Pro in Training

I had a sentence explaining enType in my post but for some reason I removed it.

enType can be for example an enum, or a char.. whatever you want. Adding a variable to each derived class as you suggest works as well, but using e.g. the virtual getType function makes things easier to maintain, as you force every class the inherits from base to implement the getType function - it won't compile otherwise.

thelamb 163 Posting Pro in Training

You can add some 'type' variable to the base class, that you set through its constructor.

class base {
  enType type_;
public: base( enType type ) : type_( type ) {} 
  enType getType() const { return type_; }
};

struct derive : public base
 derive() : base( TYPE_DERIVE_1 ) { }
};

When you call functions 'through' the base*, you're calling them on the derived object.
So, in the base class make a getType function that derived must overload.

struct base {
   virtual enType getType() = 0;
};

struct derive : public base
  enType getType() const { return DERIVED_TYPE; }  
};

Or you can template the base class based on enType.

I'm sure there are more ways, but these are the 3 I can think of right now.

thelamb 163 Posting Pro in Training

Your comments are a bit excessive, I know this is something very personal but generally you'll want to have few comments that help understand the code, not comments that repeat what the code says. Don't take this too harshly though, I am really a comment-minimalist.

E.g.

#include <iostream>		// For Standard C++ console IO facilities
#include <string>		// for std::string
#include <Windows.h>	// For WinAPI facilities

Any somewhat-experienced C++ coder will know what these headers are for

int indicateSign(int birthDay, int birthMonth);
// Arguments: 2 ints, as birthDay-birthMonth
// Return: int, as the zodiac order number correspondent with birthDay-birthMonth

Commenting function input/output is ok, but I'd suggest to use a 'standard' format like Doxygen, so that you could also easily generate project documentation just by running Doxygen. And people reading your code, who are familiar with Doxygen will know exactly where to look.

For me, personally(!), the massive // *** <something> *** ==================== is very cluttering. When I am looking for e.g. the declaration of QUALITY I'll either use the IDE's built-in 'goto declaration' or use a search anyway.


Another example of excessive comments - "CLEAR_CONSOLE" is obvious enough.

bztConsole("CLEAR_CONSOLE"); // Clear the screen

You compare userCommand to both upper and lowercase strings, e.g.:

if ((userCommand == "E") || (userCommand == "e"))

Why not first make userCommand all lower-case and just do if( userCommand == "e" ) ?

I usually prefer to write if( "e" == userCommand ), as this …

thelamb 163 Posting Pro in Training

http://www.cplusplus.com/reference/string/string/

Scroll down to 'String operations:'.

You can use functions like find, compare etc.

thelamb 163 Posting Pro in Training
if(data[j] == ayat)

This comparison will only work if the user enters the exact string that is in the data array. This is not what the question asks, you need to come up with a way to compare parts of(the entire student ID, or part of the student name) the data[j] string with ayat.

thelamb 163 Posting Pro in Training

Ok, then there probably are some left-overs in the input buffer, as I see now from the code you posted you are actually requesting input from the user.

Have a look at this sticky:
http://www.daniweb.com/forums/thread90228.html

It explains nicely how you can flush the input buffer, after that both methods (cin.get() at the end or running with ctrl+f5) should work.

thelamb 163 Posting Pro in Training

I may have misunderstood your question.

Do you want to be able to debug your program? I deduced from your last reply that you think 'ctrl+f5' will allow you to debug the code inside visual studio, and that you do not want this.

So let's summarize:
1) 'F5' - Run under debugger, window will close when returning from main
2) 'Ctrl+F5' - Do NOT run under debugger, window will not close when returning from main.

So if you want to be able to step through your code, you have to press F5 and insert a breakpoint somewhere. Your program will then stop on the breakpoint and hand control over to visual studio, so you can inspect variables that are in scope etc.

If you just want to run the program, but keep the window open when it finishes execution, press 'ctrl+5' or add something like std::cin.get(); before the return 0;

I hope it's clear now, if not please be very specific what behaviour you're looking for.

thelamb 163 Posting Pro in Training

I'm quite sure it does not run under a debugger when you press ctrl+F5. What makes you think that it does?

Try adding a breakpoint on a line of code that surely will be executed. It should not break if you 'run without debugging'

thelamb 163 Posting Pro in Training

When you return from main, your program is terminated, this also means that the console window will close.

In Visual studio, if you execute your program by pressing 'Ctrl + F5' it will not immediately close, instead it will wait for you to press a key.

In other situations, you can prevent termination by trying to read from stdin (and thus waiting for user input).

thelamb 163 Posting Pro in Training

Then my answer still stands, m_item will be initialized based on its type ;).

If DataType is an int, m_item will be initialized as if it were written 'int m_item;'.

So if you call insert, where DataType is deduced as an integer, the compiler will emit code that treats m_item exactly as if it were an integer.

Then your question boils down to "What is an uninitalized integer initialized to"

int m_item;

Same as if you could call insert where DataType is of class A, the compiler will emit code that treats m_item as of type A, and your question is "What is an uninitialized variable of type A initialized to?"

A m_item;
Akill10 commented: Thanks +1
thelamb 163 Posting Pro in Training

You mean what value m_item will hold? That depends on the type of DataType.
It's default constructor will be called, without any parameters. If DataType is an int, it will behave just like 'int m_item;' would. Not sure if this is exactly your question though (just had an exam from 18:30 -> 22:00... I might not think clearly any more ;)).

I'm not actually sure what you're trying to do with your simplified version.

m_array[p_index] = m_item;
m_array[p_index] = p_item;

// Same as:
m_array[p_index] = p_item; // ??
thelamb 163 Posting Pro in Training

Google for 'cin' and C++.

Also, you're now using the C function for output (printf), in C++ we generally use 'cout'.

thelamb 163 Posting Pro in Training

In C++ NULL is defined as 0, so it won't make a difference.
(The use of NULL is even discouraged by some, including Stroustrup).

thelamb 163 Posting Pro in Training

Why not just:

class A {
 static int currentID;
 int uid;

 public:
     A() : uid( currentID++ ) { }
};

int A::currentID = 0;

And you can just create the objects and put them in a vector, as long as you don't have multiple threads creating objects of A they will have a unique ID.

If this is not what you want, then it's still not very clear to me what the goal is.

thelamb 163 Posting Pro in Training

What do you want to achieve with this:

B () : x(y) {  
      B <t-1> (); // What do you think happens on this line?
}

The design currently makes very little sense.

Does the assignment specifically state 'array', if so then you probably are not allowed to use a vector.

thelamb 163 Posting Pro in Training

A templated function doesn't _need_ to be defined in the header file, however it is usually easier to do so (see http://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file ).

Inline functions however need to be in the header file, this has to do with 'translation units'. If you have an inline declaration in 'inline.h' and it's implementation in inline.cpp and then include inline.h in A.h, the definition of the inlined function won't be available to A.h because it is in a different translation unit.

Also note, when you define a function inside a class body it is automatically inlined:

struct test {
 void returnSomething() { return 1; }    // Implicitly inlined
 inline void definedElseWhereInHeader(); // Explicitly inlined
};

// This must still be in the header file
void test::definedElseWhereInHeader() { 
  // do something
}
Annettest commented: Thanks a lot theLamb. Very helpful answer. +2
thelamb 163 Posting Pro in Training

You're not actually modifying the inTables[q].Items in your first loop.

for each (AoE2Wide::DrsItem item in inTables[q].Items)
{
   // item is a copy of what's at inTables[q].Items, modifying item will leave the item in inTables[q].Items in tact
}
thelamb 163 Posting Pro in Training

Run your code under a debugger (You use Visual Studio after all) to get more detailed information about the crash.

The pasted code is too long to read through when the range can be narrowed down very easily ;)

thelamb 163 Posting Pro in Training
thelamb 163 Posting Pro in Training

Google basically... if you want general information about C++ there are many good books, there is a sticky on this forum with a few good suggestions.

I THINK there are converters for C# to C++ as well, they won't do a good job on big chunks of code, but may help if you need a few functions 'translated'.

thelamb 163 Posting Pro in Training

Basically I want to be able to implement the C# code that occurs into C++ code instead.

Your question is a bit vague...
Do you want to execute C++ code from this C# program so that you can replace it 'in small parts'? If yes... don't even try.

What I think you mean is that you want some ideas on how to write / modify binary files in C++?

This is a good way to learn things though... so what I would do:
- Look at all the major classes in the C# code, it's probably a good idea to stick to roughly the same design in C++.
- Start a new C++ Project :P (don't copy any code from C#).
- Bit by bit start to implement what the C# code is doing, like(I'm guessing here):
* Read the file
* Try some random stuff, like searching in the file, changing something hard-coded etc.
* Write the file

Some things you need to know:
If you want to read a binary file, you need to open the file in 'binary' mode, look up ios::binary in fstream.
Then you just read the entire file in an array, modify what you need and write it back.


If you have any more specific questions (easier for us than kind of guessing what you mean ;)) - please do ask.

thelamb 163 Posting Pro in Training

The instance detection won't work if an Event with the same name (or any object with the same name in the Global namespace) exists (as you've discovered). In that case, as defined by the documentation after CreateMutex, GetLastError() returns ERROR_INVALID_HANDLE.

If lpName matches the name of an existing event, semaphore, waitable timer, job, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space.

Using a sufficiently random name for the mutex should eliminate any accidental name clash. As I think we've already mentioned a few times... if CreateMutex fails, your program should also exit, you've still not added this check so if someone would want to circumvent your protection they just create an Event with the same name, as nicely pointed out by mitrmkar.

I don't know what you mean with problems across LANs. The mutex is local to your computer, it does not check all of the computers on the network to see if they have a mutex with the same name. So two computers on the same LAN can both run your program one time.

However across users, only one user on one PC can run it. So if I log in as UserA, run your program and then switch to UserB, I can not run it again.
The Mutex is created in the 'Global' namespace (hence my suggestion to prepend the Mutex name with Global\ some posts back.

thelamb 163 Posting Pro in Training

My excuse is that I was doing 5 things at the same time ;) - but well spotted.

I already mentioned in one of my posts that the return value of CreateMutex must be checked, and some error returned if it failed (e.g. the handle is NULL).

I've lost where this thread is going..

thelamb 163 Posting Pro in Training

A singleton class is one that allows only 1 object of its type to be created..

But this will (as far as I know) do you no good, if you run two instances of your program there will be 1 object in each of those instances.. not violating the singleton 'pattern'


--


Unfortunately, I don't have time to test your code on my pc atm.. probably later I can

thelamb 163 Posting Pro in Training

Hmm, that is weird... maybe one of the mutexes during testing didn't clean up properly (even though windows closes any outstanding handles when a program exits).

Try a different name for the mutex.
Also, I think it is cleaner if you name it "Global\somename" - it is clearer to any reader of your code what the purpose of this mutex is then.

Edit, something silly:
try before calling CreateMutex to call

SetLastError(0);
thelamb 163 Posting Pro in Training

I don't know what exactly you mean with 'if I use the code in WinMain it doesnt start' ... can you show us what you have?

The warning makes sense.. you are creating a variable that you never use. However, I guess IF something goes wrong with creating the mutex... you also do not want to run, so you should give an error message back after checking ghMutex.

thelamb 163 Posting Pro in Training

This is a case of reading the documentation carefully:

If the mutex is a named mutex and the object existed before this function call, the return value is a handle to the existing object, GetLastError returns ERROR_ALREADY_EXISTS, bInitialOwner is ignored, and the calling thread is not granted ownership. However, if the caller has limited access rights, the function will fail with ERROR_ACCESS_DENIED and the caller should use the OpenMutex function.

With other words, the case of 'The mutex exists' is not considered an error, so the return value will not be NULL.

What you need to do is call GetLastError() and compare it with ERROR_ALREADY_EXISTS

thelamb 163 Posting Pro in Training

There are several ways...
Create a file on startup, and remove it again on exit.
If on startup the file already exists, then refuse to start.

Or.. a better way: Create a mutex in the global namespace(CreateMutex @msdn) on startup and destroy it on exit. If the creation fails with something like 'mutex already exists', then you know that your program is already running and you can exit.

thelamb 163 Posting Pro in Training

That's because the ascii value of 5 is 53 and of 6 is 54. 53+54=107.
When casting a char to an int, you get the ascii value of that character.

You're better off using frogboy's suggestion, or substract 48 from ch.

(see www.asciitable.com)

thelamb 163 Posting Pro in Training

Depends on the type you're reading..

If you store the user input as string, you can access the individual numbers(characters) just like you would with an array:

string test = "12345";
test[0]; // '1'
test[4]; // '5'
thelamb 163 Posting Pro in Training
while (start == 1)
  cout << "\n";

Those two lines will be executed forever, you need to indicate all the code that belongs inside the while loop by putting it in { }'s

thelamb 163 Posting Pro in Training
if(nextLetter==phrase[i]);

There is a ; after the if, so letterFound will _always_ be set to true.

Edit:
Also, I think it would be cleaner to use for loops instead of while... the use of while is confusing in this case, and it is very easy to forget the i=0 before the while loop...
I'd say this is better:

for( i=0; i < phraseLength && !letterFound; ++i ) 
{

}
thelamb 163 Posting Pro in Training

sizeof is a compile-time 'function'... it cannot get the size of dynamic arrays.
So, your code is very wrong... your intention is to write 3 items into a, but there is only space for 0 items.

thelamb 163 Posting Pro in Training

You can test it, by printing what the string points to:

printf( "0x%x\n", _str );

If they point to the same.. the compiler 'optimized' it, but it may very well be that it added both strings.

thelamb 163 Posting Pro in Training

The front/rear is a little confusing.

If I push two items, rear will increase by 2. front remains unchanged, but in holds() you output front.

So, that explains why holds() gives the wrong size?

thelamb 163 Posting Pro in Training

All of those strings will be in the strings section, not on the stack.

In assembly it would look like
MOV EAX, DWORD PTR[some-fixed-address]

Not all of the strings have to be loaded in memory though, they can reside on disk until necessary.

Try to compile your code and open it in a debugger, like the free OllyDbg and look at the 'strings' tab, you will see all the hard coded strings(and more) that you've used. Or you can use 'strings' on Linux - there must be a Windows variant of that as well but I don't know where from the top off my head, probably in the Visual studio tools somewhere.

thelamb 163 Posting Pro in Training

Don't think that is entirely correct. The bar is pretty much equivalent to foo, the pointer to the string is just not directly returned as in foo, but through a variable that holds the same pointer.
So the value of s is returned, not a reference to s itself.

This would be incorrect:

const char** bar()
{
    const char* s = "Hello";
    return &s;
}

This could still work if you're lucky... but the return value will point to the local variable s which at some point will be gone.

thelamb 163 Posting Pro in Training

This will work, because the hard coded strings are stored in the strings section of your executable, and s just points to that. After the function returns the string will still be there.

static storage is if you declare a variable like this:

void myFunction() {
    static int myStatic = 1;
    myStatic++;
}

The first time you call myFunction, it will initialize myStatic to 1, and increase it. The next time you call the function, myStatic will still be 2.

So static variables declared in a function body are 'persistent' over function calls

thelamb 163 Posting Pro in Training

It makes absolutely sense that this doesn't make sense at first sight ;).

void Reallocate(char* Source)

Here, Source is a _copy_ of char* Buffer. So modifying what Source points to will leave Buffer completely untouched.

Only if you modify the thing-that-Source-points-to you will also modify the thing-that-Buffer-points-to .. because they point to the same thing.

So essentially you have 2 pointers pointing to the same thing, and you modify what one of those pointers points to.


Change realloc to take a char** as argument, and hand over &Buffer, then you can modify what Buffer points to.

kerp commented: Thanks +1
thelamb 163 Posting Pro in Training

#1 : Your vector 'quantity' is uninitialized, which means you are trying to print garbage.

#2 : Your loop is suppose to _fill_ the vector, now you are just printing it out like in #1.
Also, the loop counter must be named x, not the vector itself.

So if I ask you to make the first element of

vector <double> vDouble (100);

0, how would you do it?

Edit:
- In the second for loop, the index stays an integer. The type of the index never depends on what type you store in the vector.

Also, I don't know if the teacher mentioned this... but there are 'iterators' for vectors... maybe he wants you to use them.