mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I usually tackle these problems by looking at the boundaries. In your case, you have the basic scaling factor is "energy / max" which is at most 1 and at least 0. So in any logarithmic scale (I would assume you want base 10, but that doesn't really matter), these bounds translate to at most 0 (log(1)) and at least -infinity (log(0)). So you have a bit of a problem, you see. You will have to do a bit more work to get anything sensible out of that.

So, say you have base 10, the desired output, normally, is that if the energy of one object is ten times that of another, it should be one unit bigger. Really the only way I can think of is to set some minimum value of energy. Say the minimum for "energy / max" is 10^-10, which, in log10, is -10. Then a scale function like this might work:

//this checks the lower-bound, if greater then use log10 + 10 (offset), if lesser then use 0.
double logScaleFactor = (energy > 1E-10 * max ? log10(energy / max) + 10 : 0);
..
corners[i].x = centre[0] + ( corners[i].x - centre[0] ) * logScaleFactor; //now, the scale factor will be between 0 and 10.
corners[i].y = centre[1] + ( corners[i].y - centre[1] ) * logScaleFactor;
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

When I look at this code, I remember why people don't program in C so much any more... This post probably belongs in the C programming forum instead.

Anyhow, there is one definite problematic line, that is line 28. I found it, because that's always the first thing I look at when looking for a bug: where / how is memory allocated, where / when / how is the memory freed, where / how is it used, then is the algorithm sound. (in that order of priority!). So, the error is that you allocate the space for one struct object of type List_t, then assign the resulting pointer to a pointer-to-pointer to type List_t, and then fill it up in a for-loop with bound "size". So my awesome power of deduction tells me you intended that line 28 to be:

NewTable->table = (List_t**) malloc( size * sizeof( List_t* ) );

That should help, for the rest, it's harder to tell where the problems might be, try going through that same order of priority in checking your code.

BTW, why do you double each function definition? It's the first time I see that and it looks horrible! And it is completely useless. There is no point in putting the prototype of the function right before its definition. A prototype announces the existence of a function before it is defined, to the code that follows. But if, immediately after, you have the definition itself, the prototype is completely meaningless.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

NicAx has a good point, just to add my thought: If that DLL is, as you say, tehmarto, in an encrypted resource-file in the game-data folder (and that is why you can't just do a file search for it). There is at least a chance that the game extracts the DLL to a temporary (hidden) location and then loads it from there. In that case, that program NicAx suggested might be able to find that temporary DLL while the game is running (or at least while it is loading up, because they might just delete the temporary file after loading it).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, okteta reads binary data and prints it out in hex format (to be more readable than if you opened a binary file in a text editor). So what you need to write is binary data:

ofstream myfile;
myfile.open ("output.midi",ios::binary);
char buffer[44] = {0x4D,0x54,0x68,0x64,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x01,0x00,0x80,0x4D,0x54,0x72,0x6B,0x00,0x00,0x00,0x16,0x80,0x00,0x90,0x3C,0x60,0x81,0x00,0x3E,0x60,0x81,0x00,0x40,0x60,0x81,0x00,0xB0,0x7B,0x00,0x00,0xFF,0x2F,0x00};
myfile.write(buffer,44);
myfile.close();
dorien commented: His post totally helped me out! +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

POSIX is essentially for Linux or Unix systems. POSIX is just a specification for the API that the OS needs to expose and Linux, Unix and many others comply to those specifications. Windows does not, so windows has its own things, for example, via its Win32 API.

Boost Thread library is cross-platform in the sense that it's implemented to work with POSIX and Win32 (maybe others too, I don't know). In the coming C++0x standard, all operating systems will be required to implement a common multithreading library (std::thread), which will be almost identical to Boost Thread, because virtually all the new C++ standard libraries come from Boost.

So, I can give you a simple example, working with Boost Thread. First of all, the thread functions are in the form of function objects (or function pointers, but that's not very nice to use). A function object for a thread has to have a () operator. So here is a simple example that prints the number of times a thread loop has executed, with a "quit" option:

#include <boost/thread/thread.hpp>
#include <iostream>

//function object class that will be used to run the thread.
struct PrintThreadLoopCount {
  bool* Running; //declare a flag to tell whether the thread should still be running.
  int LoopCount; //count the amount of times the loop has run.

  //constructor
  PrintThreadLoopCount(bool* aRunning) : Running(aRunning), LoopCount(0) { };
  //copy-constructor (required if default is not good enough)
  PrintThreadLoopCount(const PrintThreadLoopCount& aObj) : Running(aObj.Running), LoopCount(aObj.LoopCount) { };

  //Declare a () operator method …
Ancient Dragon commented: Always posting such great stuff :) +33
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think these functions should be a good starting point:

FindResource

LoadResource

LockResource

SizeOfResource

And to actually save this to a file, the function you have posted earlier is not good at all. Say you use the above to get a pointer (ptr) and a size in bytes (size), then you save with:

std::ofstream file;
file.open("myfile.dll",ios::out | ios::binary);
file.write((char*)ptr, size);
file.close();
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

As Duki suggested, use the Boost Thread library. You will have to install boost. This library in cross-platform and quite easy to use, and includes all the synchronization objects you can dream of. The C++0x standard will include a thread library, and that thread library will be directly taken from the Boost Thread library (Boost is the anti-chamber for the C++ standard libraries). So I would suggest you get acquainted with that library since, once the standard is out, it will be mostly the same (maybe only a subset of the Boost one), only the namespace will change from boost:: to std::.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

For starters, I don't know how to do what you want. But I do know that the code you have there is completely wrong because of the fact that the handle that is outputted by the LoadLibrary function is not by any means a pointer to the memory where the DLL is loaded into. It is some identifier that the operating system uses to handle that DLL. Loading a DLL is more complicated and intricate than a simple dump of the content of the DLL file into RAM.

Even if you could find some sort of pointer to, say, the entry point function of the DLL or its symbol table (can't remember what it is called in windows), I doubt that you could find a contiguous chunk of memory that has the exact DLL file content (their are things like process contexts, virtual addressing, static memory, pointer translation tables, etc.). When a DLL is loaded, it gets sort of split into parts that are code shared by all processes that use that DLL, parts that are process-specific and a bunch of constructs that put those together.

If all you want at the end is to find that DLL file, wherever it might be in your computer. I would suggest you just do a file search (i.e. search through all the source files for the keyword "LoadLibrary") or if you know the name of the dll, just search through system and system32 folders (and don't forget to tune the …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Some compilers don't like it when the source file does not end with at least one empty line. See MSDN.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In linux, the distributions (Ubuntu, Kubuntu, Fedora, Gnome, ..) and their families (Debian, ..) really mostly differ in where you find things in the computer (e.g. the different services and stuff your software links with). So that's why there are different "packages" for different distributions (usually by family). But really, these packages generally are just different install programs that just contain different compiled and/or linked versions of the same source code. I'm no expert though, but as far as I have seen, all open-source programs in Linux have several distro-specific packages to install the software, but only one download for the source code (compilable on any distribution of Linux). So in that case, implementing for any distro (like Ubuntu) is fine, you might have to recompile for different distros if you want to distribute the application, but even that, I'm not sure you even really need a recompilation, maybe simply a different "install" procedure, i.e. package, will do the trick.

But again, don't take my word for it. I only have experience using programs in Linux, compiling some open-source programs (rolling software versions) and programming non-commercially-distributed applications. So the above is just the impression I have on distribution of Linux software.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I just tested a similar code on my Linux machine (gcc 4.4, with only default options), and it's working properly.

Maybe, just maybe, in your compiler / std-libraries, there is an additional char_traits template specialization for a static array of chars. It would be very weird and non-standard, but it could definitely produce the exact error you are describing. The reason for this is that the std::string class uses this char_traits template class to determine the number of chars that are being appended. By virtue of the template specialization for a char pointer, it will essentially call strlen() on the pointer, which will lead to correct behavior. But, if your particular system defines a specialization for the char[N] type (N being a compile-time constant), the char_traits::length() function might output N (which would be 100 in your case) and then the entire buffer would be appended to the std::string (ignoring the null-character along the way).

But I have to repeat, this _could_ explain the problem, but it is _extremely_ unlikely, at least I would be shocked to know that there is a compiler / std-library provider in Linux which results in that behavior.

NicAx64 commented: this may be the case. +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@firstPerson: the point is not if the members make sense or not for the classes, it's about how to best implement the I/O for base and derived classes.

@gerard: Here is what you should be doing, in my opinion (and this is what I actually do in my own code):

//IO interface for all the classes:
class printable {
  public:
    //this pure virtual method will be called to print the derived class' object.
    virtual std::ostream& print(std::ostream& output) const = 0;
};
//with overloaded operators:
std::ostream& operator<<(std::ostream & out, const printable & rhs) {
  return rhs.print(out); //simply call the print method.
};


//then your own class hierarchy:
class animal : public streamable
{
  public:
    animal(const char *name):itsname(name) {}
    virtual ~animal() {}
    
    //override the print function in each class that has any new data members.
    std::ostream& print(std::ostream& output) const {
      return output << "animal's name->" << itsname;
    };
  protected:
    const char *itsname;
};
class mammal:public animal
{
  public:
    mammal(const char *name, unsigned long val):animal(name), itsweight(val) {}
    virtual ~mammal() {}
    
    //override the print function in each class that has any new data members (and call the base class method too).
    std::ostream& print(std::ostream & output) const {
      return animal::print(output) << " - " << "mammal's weight->" << itsweight;
    };
  protected:
    unsigned long itsweight;
};
class dog:public mammal
{
  public:
    dog(const char *name, unsigned long weight, unsigned long age):mammal(name, weight), itsage(age) {}
    virtual ~dog() {}
    
    //override the print function in each class that has any new data members (and call the base class …
Narue commented: Yes. +22
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Wait! are you trying to convert it to a string or a binary memory dump?

If you want a string, as a char array, like one char '0' or '1' for each bit, then use the to_string() function. Like this, for instance:

bitset<128> bits; //say you have 128 bits.
char binstr[129]; //that requires 128 chars + 1 null-char to store it in.
strcpy(binstr,bits.to_string().c_str());
woody1144 commented: Sorted a problem that I had spent 6 hours on, thanks! a* +0
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

The idea in your second solution is the right one, you want to copy the memory from the string that is passed to a newly allocated string. That's exactly correct and proper. The only problem you have is that you used sizeof() to get the length of the string. This is not the right function. sizeof() is a "function" to give the size in memory of whatever variable or type you give it. In this case, the variable you give to sizeof() is textVal which is of type (char *) which is a pointer to a character, and on your system, a pointer has 4 bytes (32bit), so sizeof(textVal) will always give 4 (on your system). That's why you get 4 characters "menu" correctly copied to the new string, but the rest is gibberish.

The function to get the length of a string (C-style string, which is actually a pointer to the first char, of course) is the function strlen(). So, replacing sizeof() by strlen() will solve almost all the problem.

Another issue is that a C-style string has a null-character at the end to indicate the termination of the string. So the actual size you need to allocate for the new string is not strlen(), but strlen()+1, for the null-char. The same goes for the memcpy operation, also strlen()+1. You can also use strcpy() instead of memcpy().

Now, what happens if myValue already points to something? You need to check that it points nowhere or somewhere …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Memory in a computer is always organized in a pyramidal way. That is, the processor can only operate on a few variables at a time (on the register, very small memory capacity at no clock-cycle away from the processor). A program can only run a small part at a time (on the cache, a few MB, at a few hundreds clock-cycles away from the processor) on a small amount of memory (the stack). The program as a whole can only be loaded into memory that is too far from the processor to execute directly from there, but which is much bigger (a few GB of RAM, a few hundred thousand clock-cycles away from the processor). And all the data and programs are too big to be stored there and need to be in the hard-disk (a couple of millions of clock-cycles away from the processor).

This stratification of memory is essential for performance and most of it is handled automatically by the OS. The OS takes care of taking chunks of code and memory from the RAM, putting it on the cache. Then your compiled program takes care of putting a few variables at a time on the register for the processor to perform one operation.

Our point is, that if you put too much memory on the RAM and try to work with it as a whole, you only get the illusion that you do work with it as a whole when actually most of that memory …

Ancient Dragon commented: Nice :) +33
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Change the type of display_Desig at a pointer to char, char *. And with the single equal sign for assignment, it should fix the compilation error.

For the rest, there at least two small things to change / add:
1. change the type of all those B_SAL, H_ALLOW... variables to float (or double), since they hold floating-point values.
2. add a line "cin.ignore();" at the end of the loop, just after "cin >> repeat". This is due to the fact that since you read only a single character, the rest of the user input will be left dangling on the input stream and repeating the loop might yield undesirable effects. You can try without that line to see what happens.

All-in-all, it's quite a good beginning!

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

But std::allocator is also forward-declared in MyClass.h, so you don't need to include <memory> in the header.

daviddoria commented: Thanks for the help! +4
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>But more than that, I've learned that when I go too fast I can get ahead of myself and these sorts of errors pop up.

Great! As additional comment, I would say that the best way to go about a problem like this is to program it incrementally. In your case, it was simple and you were able to get all the functions programmed before compiling once, but then you get some errors that pile up and it becomes harder to find and debug them. Even, on simple problems, it's a good idea to compile many times, at every new function you add, this way you know exactly what causes the error in compilation or in the output of the newly added function. Of course, as you gain experience you can write more code or even complete libraries without compiling once, but let that come by itself, no rush.

@kirennian: >> So would I be right in saying that you only include headers which are required for the classes actual header itself and that those which are required for the .cpp methods, you include at the top of the .cpp file? That makes logical sense I suppose.

Absolutely, the point is that your header is intended to be included by other parts of the software (other source files or headers). So the more things you include in your header, you possibly will increase the size of the code that includes it, requiring more compilation time, and possibly …

kirennian commented: Thanks :) +2
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>I'd also recommend putting all includes into the header file rather then the .cpp

NO absolutely not, if we are talking about best practices in coding. OP: The way you did it is fine. You include as few headers as you can in your headers and include the headers you need for the implementation in the CPP.

And yes, the error is because of the mismatch of the parameters of the function, and I'm sure of that. And your call to it is also mismatched:

DisplayTemperatures(Temperatures, NumTemperatures, AverageTemp);

You have more problems than that though. Your function ComputeAverageTemp takes a useless parameter (AverageTemp) and when you call it, you need to store the return value in you variable AverageTemp. The same goes for Low and High.

GetTemperatures(Temperatures, NumTemperatures); 
			  Sleep(1500);
			  AverageTemp = ComputeAverageTemp(Temperatures, NumTemperatures); //take the last parameter out of the ComputeAverageTemp function
			  Sleep(1500);
			  int lowTemp = Low (Temperatures, NumTemperatures);
			  Sleep(1500);
			  int highTemp = High(Temperatures, NumTemperatures);
			  Sleep(1500);
			  DisplayTemperatures(Temperatures, NumTemperatures, AverageTemp, lowTemp, highTemp); //update your header prototype for DisplayTemperatures
			  Sleep(3500);
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

NO, if only the return type differs, they cannot be overloaded (i.e. have the same name). C++ standard specifies that overloading is only for different parameters (their types or their number), not return types.

So, to have different return types. You have a few options (in order of what's easier to what's harder to do):
1. Change the name of the function to something else.
2. Pass the return variable by reference as an additional parameter to the function, and then overloading will work.
3. Add a dummy parameter to the function prototype that distinguishes the functions
4. If applicable for the implementation of the function, make it a function template with the return type as argument, and instantiate the template function explicitly.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ho, well the thing I posted is the classic debug print MACRO.

Line 3-5: This checks if the #define symbol "DEBUG_VERBOSITY" was defined through the compilation command-line arguments (like -DDEBUG_VERBOSITY=4), if not, it will define it as 5. This is the verbosity level of the debug output. This means if the first number in the call DEBUG_NOTICE() is smaller than DEBUG_VERBOSITY, the notice will be outputted otherwise it won't.

So in line 12 and 14, the 2 and 8 are the "importance rank" of the notice. This way you put the more important messages to print with a lower number (like 1 to 4 or something) and lesser important messages that you would only use when you are doing really deep debugging, would have higher numbers. This way, when you compile with low verbosity you get less debug printouts and you can turn debug printouts back on by increasing verbosity. This way you don't have to manually take out the debug printouts once you have a working software, you just leave them there and compile with verbosity 0 for the release version.

Now, line 7 is a MACRO, of course, the first parameter is that "importance rank" for the message, while the second parameter (Y) is what you would put "cout << HERE << endl;" to print the message on the terminal or console. The only other thing there is __FILE__ and __LINE__ which are standard special defines that all compiler provide, __FILE__ is the name of …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I did a bit of image processing, so I know the basic theory. I can't explain it all but I can give some keywords and methods for you to look up.

First, the problem of resolution, cropping, geometric disturbance (rotation translation scaling etc.) is pretty trivial to solve really. What you need to do is re-sample the image with increased resolution and geometry correction. The re-sampling is done with a bi-linear interpolation (or better) of the surrounding pixels. Say you double the resolution, it means for each 2x2 pixels square you need to make a 4x4 square, so for each of the new pixels you figure out where the four closest original pixels are (four corners) and do a bi-linear interpolation to get the color (or gray-scale) of the new pixel. For the geometric correction, that's just a mapping from the position of a pixel in the original image to the position of the pixel in the new image. Usually the mapping is: constant terms = translation, linear terms (x_new = A*x_old) = scaling, bi-linear terms (like x_new = A*y_old) = rotation + scaling, ... and it goes on for higher order terms like correction of fish-eye effect, etc.

Then for the comparison, well normally people use cross-correlation to compare two images. The basic idea is pretty simple. If you have two images that are the same, if you multiply each pixel-value (color or gray-scale) from the same position together and add them all up, you get …

Ezzaral commented: Nice post. +13
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, well I can put a bit of an example of a binbag: (without OS-specific flags, I don't want to be bothered, that's for you to work on)

#define DEFAULT_SIZE 4096 //or whatever.. like the size of the IP header.
class oBinBag;
class iBinBag;

class serializable {
  public:
    void save(oBinBag& B) = 0;
    void load(iBinBag& B) = 0;
};

class oBinBag {
  private:
    unsigned char* buffer;
    int pos;
    int size;
  public:
    oBinBag() : buffer(new unsigned char[DEFAULT_SIZE]), pos(0), size(DEFAULT_SIZE) { };
    ~oBinBag() { delete[] buffer; };

    oBinBag& operator <<(uint32 value) {
      //say, MSB first:
      if(pos > size - 4) {
        unsigned char* tmp = new unsigned char[size *= 2];
        memmove(tmp,buffer,pos);
        delete[] buffer;
        buffer = tmp;
      };
      buffer[pos++] = value & 0xFF000000;
      buffer[pos++] = value & 0x00FF0000;
      buffer[pos++] = value & 0x0000FF00;
      buffer[pos++] = value & 0x000000FF;
      return *this;
    };
    oBinBag& operator <<(uint16 value) {
      //say, MSB first:
      if(pos > size - 2) {
        unsigned char* tmp = new unsigned char[size *= 2];
        memmove(tmp,buffer,pos);
        delete[] buffer;
        buffer = tmp;
      };
      buffer[pos++] = value & 0x0000FF00;
      buffer[pos++] = value & 0x000000FF;
      return *this;
    };
    
    //etc.. for as many primitive types you need, but watch out for ambiguous overloads.
    
    oBinBag& operator <<(serializable& value) {
      value.save(*this);
      return *this;
    };
};

// the same but in reverse for iBinBag (with >> operators)

// Then, a typical struct like IPHeader, lets say:
class IPHeader : public serializable {
  private:
    uint8 headerlength; // header length
    uint8 version; // version
    uint8 tos; // type of service
    uint16 packetlength; …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I see two things that could be happening that makes it compile without error in VC++:

1. VC++ might actually mangle the names differently according to return type, the standard allows it even though it really serves no purpose because overloaded return type are not supported, so who knows, maybe for the VC++ linker these two functions are not ambiguous at link-time.

2. Most probably, the linker looks into one object file at a time to resolve its external symbols and once it finds a match it is satisfied and does not look any further, such as to see if there is a multiple occurrence of the symbol (which is a bit of a waste of time). This actually happened for me with GCC, there was an old version of an object file put in one lib and the newer one in another and I was getting a ton of seg-faults and stuff because the linker was linking the old version and was not complaining that there were all the same external symbols in another library (just because of the order they were send to the compiler). But still, in the same module, the multiple occurring symbols should be detecting during the construction of the symbol table, unless VC++ does not make a lib-wide symbol table when all the object files go into an executable.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I don't mean to interrupt, but usually when you want a really robust binary interface for a byte-stream. You don't cast, or stringify, or pack/pragma, or what give you. You implement a binbag with off-the-hook protection from cross-platform, cross-compiler, cross-compiling-option.. the whole shabang. Implement the binbag's interface on the model of the std::iostreams (with those nice << >> operators) or like Boost Serialization. Then you write a save / load, or send / receive, or pack / unpack, or whatever you like to call it, that will serialize or un-serialize the data by packing it into or extracting from the binbag. This way you put all the nasty conditional compilations that you will need for ensuring off-the-hook binary-compatibility, all in one place (the binbag implementation).

Just my humble input, take it or leave it.

pdk123 commented: Really helpful design option. and quick response +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

You might have a dangling newline on the cin, so when you try getline it returns an empty line before you even have time to enter anything. Simple solution, replace the "cin >> answer;" part with:

cin.ignore(); //this will ignore any newlines that are on the input buffer but not yet red.
getline(cin,answer); //then read the line.
Lusiphur commented: Good Answer :) +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well MSDN says this:

The classes in <strstream> are deprecated. Consider using the classes in <sstream> instead.

And www.cplusplus.com has no mention of strstream at all, it seems to have vanished from their standard library reference documents.

It appears also that strstream uses char arrays in the underlying implementation while stringstream uses std::string, which is better, of course.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

There are some tools for "code refactoring", I have looked for good ones that are free or opensource, but to no avail. Visual C++ has apparently very good tools for code refactoring, but I have not used them.

In this case, you want to use a serialization library like the one in Boost to do those stream in and stream out functions. There are also plenty of other libraries in Boost that can be useful for this like the preprocessor library, the template meta-programming library (MPL), or even the group Bind/Lambda/Phoenix/Spirit. You'll probably will find what you need there, try not to use scripts as code factories, the preprocessor and templates are much better options.

ithelp commented: Thanks Mike. +7
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Ok, well change the constructor parameter aPeople to the type Person** instead:

XYZ(int aCount, Person** aPeople)

The [] notation of arrays is a remnant of C, and C++ compilers don't deal well with it.
And I was wrong about the const there, if a const should be any where, it's at the end to indicate the pointer is constant, "Person** const aPeople", but don't worry about that.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I think there is no need to dig up a place in the C++ standard where it says something like: "a class Foo derived from class Bar cannot access the protected members of Bar from another object of type Bar or any other of its derived class, including Foo." Because this is obvious. The "protected" access rights are limited to the instance of the derived class. In other words, a Foo object can access ITS OWN protected members that IT GOT from ITS inheritance of Bar. For any other object that is not the "this" object, protected members are inaccessible, just like if they were private, as far as Foo is concerned or any other derived class for that matter.

This is required for encapsulation. It would be far too dangerous to allow all objects of classes derived from Bar to be able to temper with the protected members of other objects inheriting from Bar. Think about it, if that was allowed, you could easily make a dummy class derived from Bar, to do some operation on the protected members of all the other classes derived from Bar, that totally breaks encapsulation.. As they say, "with great power comes great responsibility", well a golden rule in programming is "when it is easy to do the wrong thing, don't trust any programmer to do the right thing, especially not yourself!" and access right is one of the features of C++ that tries to give you tools to help you help …

daviddoria commented: Nice explanation. +4
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Oh... small piece of code, lots of problems:

struct Person
{
    char* name; //this is a pointer to a char (or array of char, with null-termination)
    int age;

    //For good practice, use parameter names that don't conflict with data member names.
    Person(const char* aName, int aAge) //notice the "const" on aName to make it illegal for this constructor to change aName.
    {
        //this->name = name; //This is memory-horror. Setting the pointer name to aName does not copy the memory content of aName (i.e. the string).
        //This will copy the name: begin{
        int length = strlen(aName);
        name = new char[length+1];
        strcpy(name,aName);
        //}end
        age = aAge; //notice, no need for this-> when names are not ambiguous.
    }
    //It is unacceptable for a class or struct to hold a pointer without cleaning its memory upon destruction, with this:
    ~Person() {
      if(name)
        delete[] name;
    }
}

struct XYZ
{
    int count;
    //Person* people[]; //Cannot reseat an array [] type, or at least not on standard compilers. That's why "this->people = people;" caused an error. 
    Person** people;

    XYZ(int aCount, const Person* aPeople[]) //notice it is fine to send it as array[] in parameter list (but add const).
    {
       count = aCount;
       //this->people = people; // << Error here. //Again, same memory-horror as above.
       if(count) {
         people = new People*[count];
         for(int i = 0; i < count ; ++i)
           people[i] = aPeople[i];
       } else {
         people = NULL;
       }
    }
    //Again, ALWAYS CLEAN THE MEMORY!
    ~XYZ() {
      if(count) {
        for(int i = 0; i < …
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I can't help much, but I can say that usually what you are referring to is called an "edit box" not a text box. That might help you in your web search.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Why do you need two operators <<? I mean if you put the code for the second one into the first one, you will only need to do "fileOut << d;". Moreover, the second call "<< d.beamlets" is not going to work because beamlets is a private member of the DCP class. If you need the second << operator (for the vector of beamlet), then just call it inside the first one, i.e. "return out << dcp.beamlets;".

Then, this piece of code seems really weird to me:

if (it!=b.end()-2) out1 << it.left << "," << it.right << ",\n";
	    else out2 << it.left << "," << it.right << "\n";

I don't think that "b.end()-2" is meaningful at all, most probably, it is undefined behaviour, so try to avoid it. Use indexing instead of operators to check where you are in the array. And what is this piece of code supposed to accomplish? The comma at the end of the first line, in ",\n", is useless, and this way, you don't need this conditional at all.

Other then that, it seem fine. BTW, these are NOT nested classes, these are just two friend classes. But maybe beamlet should be nested in DCP.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

In your InitGeo function, you call sinf(theta) several times and theta IS IN DEGREES! That's your problem. use the angle variable instead. In the future, it might be a good idea to get used to using only radians for everything, degrees are meaningless and useless most of the time.

The rest looks fine to me.

Kanoisa commented: Much appreciated +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well from my understanding, you are sharing the objects between your different objects, i.e. the Graph and Edge objects contain pointers to shared Nodes. In this case, of course storing the objects directly is out of the question, or at least one of the two objects that hold the shared Node, must store it as a pointer, otherwise the instance of Node that is shared will not be the same (i.e. copies of each other).

So you're right to use pointers. But watch out! Typically in a graph architecture, you need to define rules of ownership (i.e. who is responsible for destroying the instance of a Node to which several other objects (Graph, Edge, Node) hold a pointer to). Then, you have to worry about the order of destruction, such that an object which holds a pointer to a Node for which he doesn't have ownership, should not access it after the owner has destroyed it. This can become quite tricky. Then, you have cycles or semi-cycles to worry about as well.

Luckily, Boost Smart Pointers give you a nice trio of smart pointers that can really help in graph-like object hierarchies: shared_ptr, weak_ptr, unique_ptr (all now part of TR1 standard library, i.e. tentative release 1). A shared_ptr is a reference-counted pointer, meaning that it will automatically destroy only when all copies of that shared_ptr are deleted or gone out-of-scope. This can allow you to make sure no pointers to a Node will suddenly point to the freed …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

On the main() function, see this SO-thread. Your prof is wrong on this matter. Even the original C standards have always defined main as returning an int, although the old standards allowed to omit the return type, in which case the int type was implied. This was changed in C99 standard and is no longer allowed. Also, it is possible that compilers accept a non-standard void main(). Finally, some C compilers may not complain if you don't give a value to return. Thus, in some weird old-standard inspired, but non-standard C compiler, this would be possible:

main() { //here return type is omitted but implied as int, not void.
  ...
  return; //or no return statement at all. All compilers I know would not allow this.
};

You are right about the wide-chars, they occupy two bytes of memory but represent one character. I don't know exactly how you write a literal wchar_t that has a non-ASCII value (> 0xFF), but still, it's not with 'ab' for sure.


Instead of arguing with your prof. Put him in front of a computer with C / C++ compilers (which are strictly compliant with the latest standard C99 and C++03 or C++0x-draft) and ask him to compile his own code snippets.

nbaztec commented: Thank you. +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@AD: <string> is technically part of the C++ standard library, not the C++ standard template library (STL), these are two distinct libraries.

Ancient Dragon commented: right +31
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

NO

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Your problem is that a function pointer is essentially a C feature and does not support methods (that is a function acting on an object). So you can only make function pointers to static class methods or global (or namespaced) functions.

>>As i think you can see i basically want the logger to be able to be set in either mode (at any time but i only intend to use it once at the start)
Why not use polymorphism? Try something like this:

/* logger.h */
class Logger
{
  public:
    bool CreateLog(const std::string &name, bool overwrite = true);
    void Write(const std::stringstream& stream);
    void CloseLog(void);
    virtual ~Logger() { };
  protected:
    virtual void WriteLog(const std::stringstream &stream) = 0;
    std::ofstream log;
};

class SyncLogger : public Logger {
  protected:
    void WriteLog(const std::stringstream& stream);
};
class AsyncLogger : public Logger {
  protected:
    void WriteLog(const std::stringstream& stream);
};
/* logger.cpp*/
void Logger::Write(const std::stringstream &stream)
{
	WriteLog(stream);
}

void AsyncLogger::WriteLog(const std::stringstream &stream)
{
	log<<stream;
}

void SyncLogger::WriteLog(const std::stringstream &stream)
{
	log<<stream;
	log.flush();
}

Then at the start, you create either a SyncLogger or a AsyncLogger depending on the case.

There are many other solutions also, that I'm sure will come up on this thread. But function pointers is really not a particularly good one (I would say the worst.. function pointers are deprecated in C++ as far as I'm concerned).

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Sure, you can use a dynamic array. I could say you can use a linked-list too, but that may be to big a step. So, yeah, if you didn't get to std::vector in your class, then I guess you should use a dynamic array, but it will be a bit more work for allocating and reallocating new memory for each add student. But if he didn't forbid you to use vectors, then maybe it's worth a look.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>> >>it[switch statements] doesn't make the slightest difference at the end

>>On the contrary it does. Switch statements are easier to read, cleaner, and faster
>>than ifs/else's.

OK well, to me that's a matter of opinion.. frankly I have never understood the purpose of switch statements in an object-oriented software design, and I (almost) never use them. So, I never liked them, never got used to them, and never found them easier to read or cleaner, I just find them useless and cumbersome. But you're right, they are faster, for contiguous integer case-values (or enums, of course), but not for strings (like in the OP) and most other types.

>> >>But, to be even more on the C++ side, you can use function objects

>>And to be even more more towards C++ side, you can ditch the new and delete command
>>for now, and let smart pointers handle it.

Sure that's a good point, and "delete" statements are a very rare occurrence in modern C++ code with smart pointers (in mine also, of course). But I omitted that point for a good reason: I like to preach awareness of memory management issues as a vital part of the understanding of computer programming, before giving more advanced tips. Crawl -> Walk -> Run.

Aranarth commented: Agree +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

I am using a switch statement, so they must be constant

Then don't use a switch statement. The switch statement is just shorter (a bit) to write then "if () {} else if () {} ...", but it's fundamentally the same. So if it is not convenient for you, don't use it, it doesn't make the slightest difference at the end.

I don't recommend you use the code from Ketsuekiame (for many reasons I won't get into). But if you want to implement a similar strategy and I understand you are allowed to use some C++ constructs, then use "std::map" in the standard header "#include <map>". You can make it as this (in the flavor of Ketsuekiame):

#include <iostream>
#include <string>

bool FunctionOne() {
   cout << "Function One Called" << endl;
};

bool FunctionTwo() {
   cout << "Function Two Called" << endl;
};

typedef (bool)(*commandFnPtr)();

std::map< std::string, commandFnPtr > lookUpTable;

bool ExecCommand(const std::string& functionName) {
  std::map< std::string, commandFnPtr >::iterator iter = lookUpTable.find(functionName);
  if(iter != lookUpTable.end())
    return (*(iter->second))();
  return false;
};

int main(int argc, char** argv)
{
  lookUpTable["command_string1"] = &FunctionOne;
  lookUpTable["command_string2"] = &FunctionTwo;

  for(int i=1;i<argc;++i) {
    if(!ExecCommand(argv[i])) {
      std::cout << "An error occurred during command '" << argv[i] << "'. Terminating application..." << std::endl;
      return 1;
    };
  };
  return 0;
};

But, to be even more on the C++ side, you can use function objects (because function pointers are essentially deprecated in C++). And you will get nice additional benefits with it such as data members that can be …

StuXYZ commented: Clearly explained. +3
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First of all, for any type (string or other), the statement "if ( a = b )" does not check whether a is equal to b, it assigns the value of b to a, and returns the final value a (which is also the value of b). The single = sign is an assignment operator, not a comparison operator. The comparison for equality is ==, i.e. double equal sign.

Second, the strings that you are using are so-called C-strings (kept for legacy support of C code in C++). The proper string to use is the class "std::string" (in the "#include <string>" header. Using these, your code will work (with the double equal sign instead of single equal sign for comparisons).

Third, if you have to use "char *", i.e. C-strings, then there is no equality operator for it, so "a == "yes"" will not work. The proper function to compare two C-strings is strcmp(), which will return 0 if they are equal. Thus:

if( strcmp(a,"yes") == 0 )

Finally, and most importantly, having "char* a;" does not initialize "a". "a" is a pointer to an array of characters (char). By not initializing it, you have a pointer that points nowhere (well it points somewhere, but not somewhere that it should point to, because the memory at that address will be used for something else and using "a" uninitialized will corrupt your program). So, you need to initialize it by giving some space for it. Since you are …

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well, I agree with jonsca, use a while loop. You can also use "continue" to come back to the start of the while loop from anywhere inside the loop.

If it really is not going to work with a while loop, do everything you can think of to make it work... and if all else fails, C++ still supports the infamous "goto" statement.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

@AkashL: The auto_ptr will help because it will make sure the "paramTime" in this case is deleted before main() exits, but it is not ideal because, as you said, it is not reference counted, so if the pointer is copied to other functions and stuff, it will get deleted at the first scope that it leaves and its copies will be pointing to a deleted object (very bad, of course).

The unique_ptr is better for two reasons. First it is non-copyable, it's guaranteed that it will not be sent anywhere that is outside the original scope, and will be automatically deleted at the end of the scope (as for that auto_ptr). Second, a unique_ptr is packaged with a deleter (optional parameter to the constructor of unique_ptr), this guarantee that the delete operator used to free the resource is the right one (this is extremely useful for cross-module implementations, where multiple heaps are involved in the overall application).

So the conclusion is that auto_ptr is not very safe in general. shared_ptr/weak_ptr and unique_ptr are more useful for the copyable-reference-counted case and the non-copyable case, respectively.

@bleedi, if you are using linux, try valgrind to diagnose memory leaks and other memory-related issues.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

>>Well, if the sum of the length of two (hypothetical) sides is greater (or equal) than the other, it can't be a triangle.
I think you meant to say: "if the sum of the length of two sides is LESS (or equal) than the other, it can't be a triangle.

mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

p->next will be NULL for sure, do you see any line in addNodeAtFront() which starts with "next =".. the answer is no. So next will start with the value NULL and will remain that way.

I think you have mixed up front and next in your addNodeAtFront().. not entirely, but enough that I can't understand where the new node that is added should stand, and what exactly front and next point to, in the whole scheme of things.

Think of a linked list as a chain (excuse the ascii artwork, and I will use prev for what I think you call front):

NULL
 ||
prev <- node1 -> next
          ||      ||
         prev <- node2 -> next
                           ||
                          NULL

So to insert a node between node1 and node2 from the above, you need to set the new_node->prev to node1, node1->next to new_node, new_node->next to node2 and node2->prev to new_node. All these are accessible from either node1 or node2 (hence, a bi-directional linked-list). If you are implementing a unidirectional linked-list, then it is the same business but simpler, and of course, you can only add elements in one direction.

But again, I'm not sure of what you want to accomplish, what does length really mean in a linked-list? The idea of a linked-list is that it is decentralized, i.e. you shouldn't need any oversight as to the length, to go through the list in one direction, you start at the first node and follow the next pointers until …

figuer25 commented: Thanks man +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

First off, I can't help on the AT side, but I know matlab pretty well. There are essentially two possibilities: either run in matlab and use DLLs to interface to C++ code to deal with AT commands and whatever else, or compile matlab using RTLab. So if you are in matlab, you can wrap all you C++ code inside some dynamic link libraries (DLL) and call them from matlab (all I know how to do is from SimuLink with SFunctions). Otherwise, you need the package RTLab in matlab which allows you to compile the matlab code into a DLL and then call it from your C++ code. One way or the other is a bit of work.

So third option, if all you need to do is some image processing in matlab, why don't you use the library OpenCV (Open-source Computer Vision libraries)? They have all image processing, stereo vision, matching, filtering, etc. etc. functions built-in as c++ code, so that would solve the problem. I know people who use this library and apparently it is very good!

Generally speaking, interfacing matlab and C++ is rarely worth the trouble because most matlab code can be translated into C++ quite easily, and it executes much faster.

jonsca commented: Good points +4
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well for small projects it ok to put everything in the header files, but as the project grows it will become more and more inconvenient. Since you have read stuff on C++ I will not repeat to much that the "philosophy" behind headers and cpps is to declare classes and functions in the header and implement (or define) them in the cpp.

In practice, when you compile a C++ project, you typically compile a bunch of cpp files together in an executable, an object file (.o), a static library (.a or .lib) or a shared library (.so or .dll). These contain the executable code, already compiled. So in the case of object files and static libraries, they contain the compiled version of your implementation (in the cpp files) and what they contain is declared in all the header files relevant to which cpp files you compiled into these object files and static libraries.

So.. what difference does it make to put code in cpp or header? Well header files are included all the time by other headers, other libraries, other parts of your project in general (think of it as other packages, in Java). So the more code you put in the header files the more stuff you require the compiler to compile for every individual part of project you are compiling. This will increase code size, and worse, increase compilation times (and it will get very annoying, very quickly!). Putting code in C++ files and nothing but …

StuXYZ commented: excellent summary +3
Aranarth commented: Nicely explained +1
mike_2000_17 2,669 21st Century Viking Team Colleague Featured Poster

Well this is possible:

class clsMyClass {
	private:
		unsigned int id, nodStart, nodStop;
		float pipeLen, pipeDiam;
	public:
		void AddElement(clsMyClass element, list<clsMyClass>& elements);
};

//.. in cpp
void clsMyClass::AddElement(clsMyClass element, list<clsMyClass> &elements)
{
        //.. do whatever extra thing you like here.
	elements.push_back(element);
        //.. or here.
}

//main.cpp:

int main() {
  //...
  list <clsMyClass> pipes;
  //...
  pipes.back().AddElement(element,pipes); //see here you have to access back() to call AddElement.
  //watch out that back may not exist if list is empty.
  //...
};

But I would not recommend doing this, it is bad design, too convoluted. Implement your own list class. And if at the lines where I wrote "do whatever extra thing you like here... or here.", you have nothing more to put, then just use list the conventional way:

class clsMyClass {
	private:
		unsigned int id, nodStart, nodStop;
		float pipeLen, pipeDiam;
        public: 
                //.. public interface..
};

//main.cpp:

int main() {
  //...
  list <clsMyClass> pipes;
  pipes.push_back(element); 
  //...
};