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

Yes, so how should you go about 'debugging' this?
First, look at the line where you got this error:

cout << p1[i];

Here, you say 'print the ith element of the array p1'. Now lets look at how p1 is declared:

double p1 = *p++;

It's a double!, not an array of doubles.

You should simply discard 'p1' and use 'p' everywhere:

cout << p[i];
thelamb 163 Posting Pro in Training

Your question is impossible to answer. How am I suppose to give a value to how difficult it will be for you?
All I know, from my own experience, is that for me it is easiest to learn a language by just starting to write a project in it. This doesn't need to be a useful program, the important thing is to start writing code, and to start shooting yourself in the foot so that you learn what not to do.

Also, print out a copy of the standard (or keep a PDF if you don't want to print ~700 pages double sided) and try to look for things in there when you're stuck, it will teach you 'how' to read the standard, and give valuable insight.

Also the game development question is difficult to answer. I imagine being _very_ comfortable with C++ is a prerequisite, it will probably also help if you've made a game yourself, or helped in developing an open source game (and you can prove that you did).
But this is all just guessing, don't expect to become good enough in C++ within a year though.

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

And now we have to guess what the problem is, right? Why don't you help us out and tell us what you're having problems with, ok? Makes things a lot easier for the people willing to spend time trying to help you.

thelamb 163 Posting Pro in Training

If you only read the elements of a then everything is fine, yes.
Also, please don't be so lazy to write 'd' for 'the' - it is very annoying to read sentences like that.

thelamb 163 Posting Pro in Training
char* a[10]={"asd","QWE","ghj"}

On this line, you are assigning const char* (everything between "'s) to a char* (elements of a).
So when you try to modify something at a[1][1] you are trying to modify a const char* indirectly. Because this constant data ("asd", "QWE", etc.) is stored in a special read-only section in memory you are getting a segmentation fault.

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

_TCHAR is typedef'd as 'char' when your project uses 'ANSI' settings, it is typedef'd as 'WCHAR' when your project is unicode.

wprintf is just like printf, but instead it takes a const WCHAR* as input, not a const char*.

L before a string literal ("string") tells the compiler that this is a UNICODE string. Without the L you would get an error 'no acceptable conversion from const char* to const WCHAR*', as then the compiler would treat " ----------\n" as an ANSI string.

Btw, you should never deal with void main, main should always return an int.

thelamb 163 Posting Pro in Training

Yes there is, e.g. in the 'singleton' pattern. Or when you have a global static class that holds objects that should be modifiable.

Usually though, you are right that you don't want to do this. But returning a const& is very common, for example in getter functions.

thelamb 163 Posting Pro in Training

And now what? What is your question?

Please don't say "it doesn't work".

thelamb 163 Posting Pro in Training

The problem is in these lines:

Point start, end;

Point(double x, double y) {
      this->x = x;
      this->y = y;
}

Your Point class has one constructor, that takes two arguments. However, no where in the Ray class you tell it what the arguments should be. So the compiler is assuming that you want to call Point's default constructor. This default constructor has no arguments and only gets generated when you don't implement any other constructor.

So in this case you did implement another constructor, so the default constructor is not created.

What you want to do is specify how to create the start and end Points, since you want to copy them from the values passed in the Ray's constructor, you need to write:

Ray(Point start, Point end) :
    this->start( start ),
    this->end  ( end ) 
{
   // constructor execution
}

What this will do is call the implicitly generated copy constructor of the Point class.

This syntax is called an initialization list. The reason this special syntax is needed, is that when the constructor starts to execute, the object already needs to be created. So it needs to know how to create all of the member variables.

Another note: You should probably rename Point start, end; in the Ray class, then you don't need to use this->start in the Ray's constructor.
It is 'customary' to prepend private member variable with m_ or append them with _ (so m_start or start).

thelamb 163 Posting Pro in Training

Ok I wonder why I even have to ask this, but:
What problem do you still have?

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

I'm not going to read your code, it is messy.

In general, say you have two singly linked lists p and q. To link them together, you can simply make the last element in p point to the first element of q.

In pseudocode:

LinkedList p,q;

// traverse to the end of p
while( nullptr != p->next )
    p = p->next;

// We're at the end, now point the next element to the beginning of q
p->next = q->first;

In case you wonder, nullptr is a c++0x feature which should be used to 'replace' the use of 'NULL' and 0 in 'old-style' C++.

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

Ok, this works but is not very dynamic. What if you later decide to change MAXSTUDENTS to 300? Then you will have the same problem as before.
Also.. your loop does not really make sense, you do:

function add 
{
   info( 200 );
   for( i = 0; i < MAXSTUDENTS; i++ ) {
      // add new student
      break;
   }
   // ask user what to do
   case 1: 
     add();
}

So your for loop is only ever executed one time.

thelamb 163 Posting Pro in Training

Ok, that is much more readable.
Do you understand my last post and how you can apply it to your code?

thelamb 163 Posting Pro in Training

Ok then you do not understand yet.
Take a look at this code:

vector<int> vInt;
for( int i = 0; i < 200; ++i ) {
   vInt[i] = 4;
}

This will set the first 200 elements of vInt to 4, but just like your code it will crash because there is no memory allocated for the 200 elements.
vector has a member function called 'push_back' that will allocate the memory, and add the element:

vector<int> vInt;
for( int i = 0; i < 200; ++i ) {
    vInt.push_back( 4 );
}

This will work just fine.

You can also specify when you define vInt, how many elements should be pre-allocated:

vector<int> vInt(200);
for( int i = 0; i < vInt.size(); ++i ) {
   vInt[i] = 4;
}

As you have a vector of some structure, you may need to do a little more work but I'll leave that to you as you still did not fix the code tags in your original post, it is impossible to read.

thelamb 163 Posting Pro in Training

Right, that makes sense. Lets have a look at the function add:

int size = Options::info.size();
for (int i = size; i < MAXSTUDENTS; i++)
{
   // here you access info[i]
}

What if MAXSTUDENTS is bigger than the current size of 'info' ? Then you're going to index elements in info that do not exist.

Does that make sense to you?

thelamb 163 Posting Pro in Training

I suppose that is a debug assertion you're getting? You should also mention on which line (and don't put spaces in the code tag).

Usually it means that you're accessing some_vector, but since the vector is indexed from [0...size-1] this is out of range. Without proper code tags your code is a little hard to read.

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

Run the code under a debugger, then tell us on which line it segfault.
If you run windows, you can use Visual Studio or whichever IDE you use.

You can't really expect people to invest time into reading your code (or copy/pasting + compiling themselves), when you can easily pinpoint where the error is yourself.

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

If I remember right, partial template specialization is in the C++0x standard. I don't know if you can do it on one member function like you want though. Haven't looked into it yet as afaik it's not implemented yet in VS.

Also, the enable_if stuff Mike mentioned is in C++0x, and already implemented in VS2010.

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

Because 0+2+4+6+8+10+12+14+16+18+20 = 110?
What do you think the output should be.

thelamb 163 Posting Pro in Training

Because what you're passing on line A is not a pointer to nVal, it is a pointer with value 65, and you are printing the value of the pointer.
On line B you pass the address of nVal, so a pointer with value 2359119.

So in the first case you are not accessing the value of nVal, you're reading a copy of nVal, just casted to a pointer.

thelamb 163 Posting Pro in Training

C++ programming language is more a reference book (at least that is how I use it). I don't know the first two books you read, but if they gave you a good basic understanding of C++ then I would try to start a project. This is the best way of learning a programming language for _most_ people (including myself).

Start small, if you're stuck take the C++ programming language book(or google) and try to figure out as much as possible about the thing you're stuck with. If you're still stuck or you managed to move on but want to know why something happened etc. then post here ;).

thelamb 163 Posting Pro in Training

It is compiler dependent, and you should not need to worry about it.
In fact, my output is :

3740816
3740872
3740928
3740984
3741040
3741096
3741152
3741208
3741264
3741320

new can allocate memory anywhere on the heap, there is nothing that says that two consecutive calls to new allocate two blocks of contiguous memory.
The compiler will take things like memory alignment(and more) into consideration when it 'decides' where to allocate.

Is there a special reason you want to know, or just curiosity.

thelamb 163 Posting Pro in Training

Some comments...
Do you understand now why you need the extern keyword?

Your use of include guards is a little over-the-top. Placing the #ifndef ... around #include statements normally results in faster compilation, but in my opinion it is way too messy if projects get bigger.
Generally, if you use a modern compiler and put '#pragma once' in the header file the compilation speed is already considerably faster compared to just #ifndef... in the .h file. So putting it also around #include ".." will probably not even give any noticeable advantage.

Also, if you created the DLL there are easier ways to link with it than on run-time. Especially if they're in the same solution in Visual Studio, but the exact answer kind of depends on which version you use, if any of course.

thelamb 163 Posting Pro in Training

You're compiling the code with unicode support. If you look at how szExeFile is declared, you'll see:

TCHAR     szExeFile[MAX_PATH];

Because you compile with unicode support, the compiler expands 'TCHAR' to 'WCHAR', which is a wide character.

So in your project settings, you should compile with 'multi-byte support', or change procname to TCHAR as well, and make sure the rest of your application is unicode.

However, if you fix this it will still give the same error. szExeFile is a fixed-length array, but the str*cmp functions take a char*.

You can do this by passing &pe32.szExeFile[0] to these functions.

Also note, it is better to use _strnicmp instead of _stricmp, as this takes a size parameter. If you decide to convert your application to unicode you need to use _wcsnicmp (this is off the top of my head, excuse me for typos).

thelamb 163 Posting Pro in Training

I can give you some hints for improvement, but you have to try and fix them yourself first ;):

* What happens if a user does not enter 'E' or 'L', but for example: "Hello I am trying to crash your program by entering text that you do not expect!" ?
Similarly, what happens if they enter 'A', or 'e' ?

* What happens if your program can not open the outfile? Maybe you don't have permissions to write the file, etc.

* It looks like delta_t is used as a constant value. It is good to be explicit when it comes to constness, so declare delta_t as const:

const double delta_t = 0.01;

* vn += ((vn^b)*delta_t);
Its hard to judge if this is correct, as these operators (+= and ^) are implemented the threevector.

* if (t == 0.0)
Comparing doubles is dangerous, you can not really do it precisely.

* It may be more clear to whoever is correcting your code to split the work up into functions.

That's all I have time for right now, hope it helps.

Please mark the thread as solved when it is.

thelamb 163 Posting Pro in Training

It assigns 'E' to determinant, the assignment succeeds so the overall statement is interpreted as true.

thelamb 163 Posting Pro in Training

Your StateList is defined as vector<int>::iterator.
StatesPicked is vector<std::string>.

So StatesPicked.begin() will return a vector<std::string>::iterator, not vector<int>::iterator.

Also, why do you do StatesPicked.begin() + N ? N is 0 so what would be the effect?

If you're able to use C++0x features, you can write the code like this:

#include <algorithm>

std::for_each( StatesPicked.cbegin(), StatesPicked.cend(), [] (const std::string& state) {
    std::cout << "State picked: " << state << "\n";
}
);

This weird looking [] () is called a 'Lambda'.

thelamb 163 Posting Pro in Training
if (determinant = 'E')

This will _always_ be true, note that in C/C++ if you want to compare two values you should use '==', not '='.

I'd suggest to write the if statements like this:

if( 'E' == determinant )

That way, if you accidentally write = instead of == you will get a compiler error.

thelamb 163 Posting Pro in Training

Ok I misunderstood then.
You can do this with a union:

typedef union _myUnion {
    int myInt;
    char myChar;
} myUnion;

And use it like:
myUnion union;
 union.myInt = 5;
 union.myChar = 'a';

Stack<myUnion> UnionObject

Note that a union's size will be the size of the largest time it contains, so in this case sizeof( int )

I hope this is what you want to do. If not, please be more specific... like include an example of what you want.

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

Did you clean and rebuild the project? If so, can you paste the code surrounding the error?

thelamb 163 Posting Pro in Training

You can just give 2 (or more) template 'variables':

template< typename A, typename B >
class TwoTypes
{
   A a_;
   B b_;
};

And use it like:
TwoTypes<int, char>
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

No, your error handling is not exactly correct. I've seen many of our students do the same as you did though.

What exactly is pthread_exit meant for? To exit _from_ a posix thread. But in your case the thread that calls pthread_create is not a posix thread. So you can just exit();

Also, there is a special output file descriptor for error messages, called stderr. It is better to print errors to this, instead of to stdout like you are doing now. You can use fprintf for that.

Now on to your array problem. You need to understand that an array in C is basically a pointer. When you write int A[x]; where x is initialized as atio(argv[1]); you are using a feature from C99, you should make sure that your teacher agrees with this.

I think your teachers intention is that you use malloc to allocate a 2D array, and pass that to the functions. I will show you how to do it with a 1D array then it's up to you to extend this to 2D.

// in main:
int* A = (int*)malloc( x * sizeof(int) ); 

pthread_create(&tid,&attr,matrixA, (void*) A);

// in matrixA
... matrixA( void* param ) {
    int* A = (int*)param;
    // use A here 
}

If you want to pass a struct to the thread:

typedef struct threadArgs {
    int* matrixA;
    int* matrixB;
} threadArgs_t;

int main() {
 // creating matrix A and B

 threadArgs_t threadArgs;
 threadArgs.matrixA = A; …
cbreeze commented: helped me a lot +0
ddanbe commented: Great help. +15
thelamb 163 Posting Pro in Training

Please don't immediately ask how to do something... you've already done exactly what you have to do elsewhere in the code! How do you initialize a string?

thelamb 163 Posting Pro in Training

I've only glanced over your code, this caught my eye:

case 1:
          Fmonth = 'January';

What compiler are you using? This line should generate an error among the lines of "too many characters in constant".

I don't know if this is the cause of your problem, as it should not even compile. The easiest way is to run your code under a debugger and step through the code to see exactly what is going on. If after you do that, and you still don't know what is happening you can probably at least give us a more detailed description of the problem and show us what you've already eliminated.

thelamb 163 Posting Pro in Training

I'm not really sure if I understand your problem, because as far as I can see you are already have all of the knowledge to solve it.

Your question is how to pass the two matrices to the thread that is going to multiply them. And you say that you can only pass a struct.
I think that already solves your problem? You can put anything that the runner function needs in a structure, and then pass it to pthread_create.

Also a general comment on your code, you do almost no error checking. What happens if malloc can't allocate the memory you're requesting? Or what if one of the pthread_create functions fail? I assisted in a course on Operating Sytems at my university, a lot of points were deducted for these kinds of errors.
It is _very_ important to always check return values of functions.