ArkM 1,090 Postaholic

1. When we add a half of the next digit range (0.00000005) we do not know that it's 1/3 and 0.33333334 is a "better" approximation (if we know then we add 0.000000033333333, of course ;)). We add 0.00000005 to ALL numbers. Don't forget: it's only one of possible floating-point promotion solutions and we need special studies to prove its (dis)advanatages. In practice we all use builtin float to double promotions.

2. Well, try ALL float fractions (~10000000) and you will find yet another cases ;). Or better try all double fractions (~10000000000000000)...

I hope today you know why it was a buzzing under engine cowling...

ArkM 1,090 Postaholic

Pay attention: 0.33333335 is a better approximation of the periodical fraction 1/3 than 0.33333330...
Sometimes it's a very useful method to round off numbers.

ArkM 1,090 Postaholic

Some addition.
In real world floating-point arithmetics (float, double and long double types in C) based on a binary representation of scaled numbers (as usually it's a binary fraction multiplied to power of 16). So you can't represent 0.7 decimal fraction as a binary fraction exactly: remember that fact.

For simplicity and clarification suppose we have CPU with decimal arithmetics. You are C compiler designer and you want to implement floating-point if expression code generator.

float xf = 1.0/3.0; /* you have 0.3333333*10^0 in xf */
double xd = 1.0/3.0; /* you have 0.3333333333333333*10^0 in xd */
/* Approximations of 10^0*0.333333..... */
if (xf < xd)
   ...

Well, the 1st op is type (precision) balancing: you must promote short value to correspondent longer type. Possible solutions:

0.3333333 => 0.333333300000000 /* fill by zeroes*/
0.3333333 => 0.333333350000000 /* add 5 in the next digital position */

You like the 1st solution: OK, now a program generated by your compiler returns true in this test. But your old fellow from AnotherCompiler, Ltd implemented the 2nd solution (why not?). Another compiler compares 0.33333335 with 0.3333333333333333 and returns false.

That's all. What's the best compiler?..

ArkM 1,090 Postaholic

Stricktly speaking it's possible and valid behaviour of floating-point calculations.
Floating point types are not mathematical real numbers. The last ones have "infinit" precision but doubles and floats are approximations of real numbers.

So C language literal 0.7 is an approximation (of double type by definition) of the real number 0.7 and 0.7f is ANOTHER approximation of this number. May be 0.7 == 0.7f, may be 0.7 != 0.7f!

Moreover, don't intend that the following code prints OK:

double x = 7.0 / 10.0;
if (x == 0.7)
   printf("OK\n");

You can read (by scanf) 0.7 from a text file but you can't intend that the number is equal to 0.7 literal from your code.
Look at your code fragment again:

float a=0.7;    
    if (a > 0.7)
      ...
    if (a < 0.7f)
      ...

The 1st if expression evaluation: promote a to double then compare with double type literal.
The 2nd: compare float a var value with float type literal.
Absolutely different operations involved...

Moral:
1. The only "trustworthy" equality tests for floating-point data are == 0.0 and != 0.0.
2. Remember that double and float values are approximations, not exact values.
3. Never use float type in math calculations: it has too low precision.

Probably it was your maiden filght over Computational Mathematics Area ;).
Bon voyage!...

ArkM 1,090 Postaholic

Stop indulge in fantasies. See iamthwee's exhaustive answer...

ArkM 1,090 Postaholic

Compile your project in VC++ 2008 as a console (not Forms) application and you will get the same result as in Code::Blocks (probably, your Code::Blocks IDE used VC++ to make console application)...

ArkM 1,090 Postaholic
ArkM 1,090 Postaholic

What data structures you consider Advanced?
Try to implement a very fast (and huge) priority queue with erase by key operation...

ArkM 1,090 Postaholic

Yes, it's one of possible solutions.
It's a matter of tastes: I prefer to declare class wrapper for pointers.
Congratulations!
Good luck!

ArkM 1,090 Postaholic

Regrettably you did not pay attention to the class Apointer in my post in your previous thread on this topic:
http://www.daniweb.com/forums/thread144299.html
The point is that you have a priority_queue<Alumnos*> now, not priority_queue<Alumnos>. So queue ordering (priority) is defined by operator>() for pointers to Alumnos, not by Alumnos::operator>(). But pointer values ordering does not bear a relation to Alumnos ordering (by edad member values).

Declare wrapper class for pointers to Alumnos with correspondent operator>() and declare priority_queue for this class. Look at my example in the previous thread.

ArkM 1,090 Postaholic

If the tree is empty the insertNodeHelper must change its parameter value - the root pointer (see the 1st if alternative). You need pass a pointer to the root pointer (or reference but it's another song), not only its value. The root pointer type is TreeNode<NODETYPE>*. So parameter type must be (TreeNode<NODETYPE> *)*. Now you can change it with *ptr.

In actual fact this mechanism works not only in empty tree case but for every new node (because of it's recursive algorithm).

The 2nd (wrong) variant sets new node pointer to ptr parameter, but it's by value copy of the pointer to the root node, not the root node pointer variable per se. So your tree never grows.

ArkM 1,090 Postaholic

I think the right solution is std::map<std::string,int> (another name of map is dictionary).
Fast search, automatic sorting + Ancient Dragon's counter - three in one solution.

ArkM 1,090 Postaholic

It seems you have much more problems, for example:

base crash(0); // why not?

How about strlen(0) in your constructor?
Yet another example:

{
    base bomb;
    // Default constructor do not initialize name member!
    ...
} // Bang! Dectructor delete something via non-initialized pointer...

How to correct:

base::base(): name(0) // Now you print true message...
{
        cout<<"base initialized"<<endl;
}

Add name==0 test in display member function.

ArkM 1,090 Postaholic

to skatamatic:
It seems you did not read or did not understand my 1st post in the thread.
It was absolutely senseless question: how to clear a tick counter.
No need to clear tick counter: better use it as is.
Or restart the process...

ArkM 1,090 Postaholic

Allow me to add some objective info to this slightly overheated thread.
Let's add more realism to these tests: we want to initialize 2D array:

const int ROW = 100;
const int N = ROW*ROW;
int grid[ROW][ROW];

I'm using AMD Athlon 5000+, VC++ 9, release, optimization for speed.
Snippet #1:

for (int i = 1; i < N; i++)
{
    iX = i % ROW;
    iY = i / ROW;
    grid[iY][iX] = i;
}

Timing result: ~180 microseconds.
Snippet #2:

for (int i = 1; i < N; i++)
{
    iX++;
    if (iX >= ROW)
    {
        iY++;
        iX = 0;
    }
    grid[iY][iX] = i;
}

Timing result: ~23 microseconds.
It seems #2 is faster then #1 with factor 8. It's a fast solution. Is it the best solution?
No, it is not.
Snippet #3:

int k = 0;
    for (int i = 0; i < ROW; ++i)
        for (int j = 0; j < ROW; ++j)
            grid[i][j] = k++;

Timing: ~15 microseconds!
All three snippets do the same job. The fastest and simplest solution - absolutely strait-forward, traditional code.

Moral: no moral ;)...

ArkM 1,090 Postaholic

Stop stop: now I don't understand you. Please, explain what do you want to do really?
If you want fill char value 0x15, use hex char literal '\x15' directly: what for this bustle with conversions of "0x15" string? If you want an array of 5 (or 8) char, declare it as char buffer[8]; - why operator new?
Please, use CODE tag for your snippets:
[code=c] your code

[/code]
We have the intruder in this thread; now one haveaclick has his/her own thread on the Global Problem of String Reversions topic...

ArkM 1,090 Postaholic

C string is an array of char. Get this array size (length of string) then make a loop swapping leading and trailing chars ( s[0]<=>s[n-1], s[1]<=>s[n-2] and so on)...

ArkM 1,090 Postaholic

Regrettably you don't understand me.

char* str = "0x15";
int value;
char* junk;
...
value = strtol(str+2,&junk,16); /* str+2 <=> skip 0x */
...
ArkM 1,090 Postaholic

From http://www.cs.brown.edu/courses/cs157/lectureNotes/huffman.pdf :

What are heaps? Viewed abstractly, heaps are nearly complete binary trees (every level is filled completely except possible for the bottom level which is filled from the left up to a point) which satisfy the heap property: every node has a key which is greater than or equal to the key of its parent.
- To find the minimum, just look at the root.
- To remove the minimum, replace it with the last key x (the one in the rightmost node of the bottom level; that node is removed), and once x is at the root, repeatedly swap x with the smaller of its two children until the heap property is satisfied.
- To insert a new value y, just add a node to the tree, at the first available spot (the leftmost non-existent node at the bottom level), put y in it, and repeatedly swap y with its parent until the heap property is satisfied.

See also nice pictures in
http://compsci.learnhub.com/lesson/page/864-building-blocks-for-data-structures
There is max heap in your terms here...

ArkM 1,090 Postaholic

Of course, atoi() converts the leading zero for you.
Skip "0x" then use strtol() function.
It's so easy...

ArkM 1,090 Postaholic

What is it: a linked binary min heap? Why linked? Why binary? Why min?..

ArkM 1,090 Postaholic

Why you want to reset system clock? Keep it simpler:

clock_t t0, t1;
t0 = clock();
// do this...
t0 = clock() - t0;
t1 = clock();
// do that...
t1 = clock() - t1;
// Now print t0, t1 and what else...

So your original timing was incorrect (from the PROGRAM START to the current moment).

ArkM 1,090 Postaholic

It seems the most interesting question is: why queue?..

ArkM 1,090 Postaholic

It's possible but it's not so easy as I said in my previous post.
The point is that std::priority_queue has not open interface to iterate its underlying container (std::vector by default or std:deque). However the C++ Standard leaves a loophole: underlying container is a protected member c. It's possible to access it from std::priority_queu derived class.
Look at this improvisation:

/// Something with type and name
class Entity
{
public:
    Entity(const char* ptype, const char* pname):
      stype(ptype?ptype:"unknown"), 
      sname(pname?pname:"unknown")
    {}
    virtual ~Entity() {}
    const char* type() const { return stype.c_str(); }
    const char* name() const { return sname.c_str(); }
private:
    string stype;
    string sname;
};
/// Generic abstract class
class Aircraft: public Entity
{
public:
    virtual ~Aircraft() {}
    virtual int bombs() const = 0;
protected:
    Aircraft():Entity(0,0) {}
    Aircraft(const char* ptype, const char* pname):
    Entity(ptype,pname)
    {}
};

class Fighter: public Aircraft
{
public:
    Fighter(const char* name, int drops = 0):
      Aircraft("fighter",name), pylons(drops)
    {}
    const char* type() const { return "fighter"; }
    int bombs() const { return pylons; }
protected:
    int pylons;
};

class Bomber: public Aircraft
{
public:
    Bomber(const char* name, double load):
      Aircraft("bomber",name), bombload(load)
    {}
      int bombs() const 
      { 
          return static_cast<int>(bombload/1000.0); 
      }
protected:
    double bombload;
};

class Liner: public Aircraft
{
public:
    explicit Liner(const char* name): Aircraft("liner",name)
    {}
    int bombs() const { return 0; }
};
/** It's not a smart pointer.
 *  We need this type to define a proper operator>()
 *  for priority_queue (priority is bombload)...
 */
class Apointer
{
public:
    Apointer():ptr(&dummy) {}
    //~Apointer() { if …
ArkM 1,090 Postaholic

Of course, you can do iterations. Don't forget: now you have pointers (not objects) in the container - that's all. I think no need in const_cast now...
Good luck!

ArkM 1,090 Postaholic

You forget to copy zero char terminated C string.
Can't resist a temptation:

char* StrCpy(char* pd, const char* ps)
{
    char* p = pd;
    while ((*p++=*ps++) != 0);
    return pd;
}

It's a classic self-made strcpy...

ArkM 1,090 Postaholic

Oh, once more remarks:
1. It's a slightly strange code:

class nuevo : public alumnos {
public:
    nuevo( string nombre, int edad ) : alumnos(nombre,edad){};
    void verificarEdad() {
        if (edad < 20)
            cout << "Nuevo" << endl;
    }

You write nuevo::verificarEdad() member function. It KNOWS that it's a class nuevo object! So why if (...)? Want to use polymorphism? Use it! No need in special data discriminator values. For example, in your class hierarchy you can write (legally)

mypq.push(new nuevo("Helder", 25000000)); // Where is error exception?

If it's not a desired behaviour, redesign your object model.
2. It's not C++ requirement but common practice is to start user-defined class names from the capitals, for example:

class Nuevo: public Alumnos {
...
ArkM 1,090 Postaholic

I don't know why your compiler gives the error (what's a compiler are you using? ). My VC++ 2008 compiles your source OK. In actual fact std::priority_queue::top() returns non-constant reference, so your original stmt#66 is OK.

Another problem: where is desired polymorphism? Alas, when you declare priority_queue<alumnos>, only alumnos part of successors will be pushed in the container! It's known as a slicing. STL containers contain objects of one and only one type.

To use polymorphism, declare priority_queue<alumnos*> and push pointers to objects into the queue. Naturally, you must correct your code properly after that, especially initialization of the queue part, for example:

mypq.push(new nuevo("Helder", 25));
mypq.push(new nuevo("Pepe", 18));
mypq.push(new viejo("Pepito", 31));
mypq.push(new medio("Juan", 21));

Don't forget to add deallocation code: now the priority_queue destructor frees only pointers but not pointed objects.

ArkM 1,090 Postaholic

The C++ Standard (9.4.2,2) allows to specify constant-initializer for const integral or const enumeration static data members only. The type double is not an integral type.

ArkM 1,090 Postaholic

I don't understand your question: what's a function? Why and where "assign a pointer to a member in a structure"?
It seems this program face is familiar ;). If you want to compute a student grade, pass a pointer to a student structure:

/* I hate struct name typenames */
typedef struct student
struct student {
    char name[15];
    /*double average;*/
    double score1,score2,score3;
} Student;
/* No need in average member in Student! */
double average(const Student* ps)
{
    return (ps->score1+ps->score2+ps->score3)/3.0;
}

char grade(const Student* ps)
{
    char g = 'Z';
    double ave = average(ps);
    if (ave >= 90)
        g = 'A';
    ....
    return g;
}
/* and so on: no need in globals! */
int main()
{
    Student students[50];
    ...
    for (i = 0; i < total; ++i)
        printf("%s: %c\n",students[i].name,grade(students+i));
    ...
    return 0;
}

Apropos, array indicies in C started from 0 for the present /* see a strange comment after i = 1: Array Counter */...
No need in i++ and total++: use total as an index in while loop then increment it, or better write simple and clear for loop:

for (total = 0; !feof(input); ++total)
{
    ...
    fscanf (input, "%s", students[total].name);
    /* Awful call: try to input name Struct's&PointerQuestionAuthor */
    /* Don't follow my advice above w/o parachute... */
    ...
}
ArkM 1,090 Postaholic

Some remarks about terminology.
The C++ Standard use clauses "variable parameter list" and "function that can be called with varying number and types of arguments" for functions with ellipsis in parameter list.
As usually authors on this forum use a rather strange term "function with indefinite arguments".
Is it OK?

ArkM 1,090 Postaholic

There is double fmod(double,double) function in <math.h> header. It calculates so called floating-point remainder of its arguments. At first sight it's a true equivalent of the operator % defined only for integral types arguments. In actual fact a floating-point remainder is not so well-defined function as a modulo operator for integers.

By definition floating point numbers are not exact values. Sometimes you may get very strange results, for example:

cout << fmod(1.0,0.1) << endl;
// printed 0.1, not (expected) 0.
cout << fmod(2e20+1,2.0) << endl;
// printed 0, not (expected) 1...

That's why operator % does not defined for double and float (approximate) values: fmod is not the same math operator as % for integral types!

ArkM 1,090 Postaholic

yes, i know, but they asked to use a struct :S

Exactly! Think about an array (or vector) of structures.

ArkM 1,090 Postaholic

It seems you have never seen such basic C++ construct as an array.
Please, take your text-book on programming then search and study "An array" part.
After that you will never write functions with v1, v2, v3, v4 and so on parameters.
Moreover, you will never invent the only global struct and horrible ifs cascade to solve so simple problem...

ArkM 1,090 Postaholic

No standard functions to scan directories.
On Windows use FindFirstFile/FindNextFile API, for example:

#include <windows.h>
#include <string.h>

void DirScanStub()
{
    const char dirName[] = "c:\\temp\\";
    const char dirScan[] = "c:\\temp\\*.*";
    char* pname = 0; /* File name buffer */
    WIN32_FIND_DATA info;
    HANDLE h = FindFirstFile(dirScan,&info);
    if (h == INVALID_HANDLE_VALUE)
    {
        /* print message?.. */
        return;
    }
    pname = (char*)malloc(MAX_PATH); /* (char*) for C++ only */
    do
    {
        if ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            continue; /* skip directories */
        strcat(strcpy(pname,dirName),info.cFileName);
        /* Now we have the next file name...    */
        /* Open, process then close the file ...*/
    } while (FindNextFile(h,&info));
    FindClose(h); /* Close dir scan */
    free(pname);
}
ArkM 1,090 Postaholic

Probably the better word was "solved": it's my terrible English, sorry...

Some remarks.
Naturally, I have used my stop-watch class based on the Performance Counter Windows API (see URL in the source). I have tested it with VC++ 2008 only.
On other platforms we need time interval measurement tools based on non-standard API because of the best standard RTL timing clock() function has too low precision.

/* I have #include "stdafx.h" with
#include <iostream>
#include <valarray>
#include <vector>
*/
/// Original function (std:: prefix added)
void DSP_fir_gen1
(
    std::vector < double > *x,
    double *h,
    std::vector < double > *r,
    int nh,
    int nr
)
{
    int i, j;
    double sum;
    (*r).clear();
    for (j = 0; j < nr; j++)
    {
        sum = 0;
        for (i = 0; i < nh; i++)
        {
            sum += (*x)[i + j] * h[i];
        }
        (*r).push_back(sum);
    }
}

typedef std::vector<double>   Vector;
typedef std::valarray<double> Valarray;

/// Based on std::valarray:
void DSP_fir_gen1va
(
    const Valarray& x,
    const Valarray& h,
    Valarray& r,
    int nh,
    int nr
)
{
    //int i, j;
    double sum;
    //(*r).clear();
    for (int j = 0; j < nr; j++)
    {
        sum = 0;
        for (int i = 0; i < nh; i++)
        {
            sum += x[i + j] * h[i];
        }
        r[j] = sum;
        //(*r).push_back(sum);
    }
}

const int NR = 36656;
const int NH = 25;

// StopWatch = http://www.daniweb.com/code/snippet916.html

void TestDSP()
{
    StopWatch tick;
    double t;
    {
        Vector x(NR,1.0);
        Vector r(NR,2.0);
        Vector h(NH,3.0);

        tick.reset();
        DSP_fir_gen1(&x,&h[0],&r,h.size(),x.size()-h.size()); …
ArkM 1,090 Postaholic

Because of this thread is not closed yet, allow me to add some remarks.
On my AMD 5000+ (~2.6 MHz) with VC++ 2008 (release, optimize for speed) this function runs ~3.8 milliseconds (data sizes are 36656 and 25).
It's interesting that a variant of this function with std::valarray<double> data runs ~1.3 milliseconds only:

void DSP_fir_gen1v
(
    valarray <double>& x,
    valarray <double>& h,
    valarray <double>& r,
    int nh,
    int nr
)
{
    double sum;
    //(*r).clear();
    for (int j = 0; j < nr; j++)
    {
        sum = 0;
        for (int i = 0; i < nh; i++)
        {
            sum += x[i + j] * h[i];
        }
        r[j] = sum;
        //(*r).push_back(sum);
    }
}
ArkM 1,090 Postaholic

fstream.h in Visual Studio 2005? Impossible! Your program gets old stream library includes (with .h names) in old Visual Studio include directory. Check up your installation environment. May be, you try to compile old (legacy) project.

ArkM 1,090 Postaholic

Some additions:
In most of C++ implementations reinterpret_cast do nothing (like formally incorrect union trick, see Radical Edward's note). If you want to make a trick, do it honestly (it is open to question, of course ;)). It follows from this that reinterpret_cast is "better" than union trick (in the spirit of C++ language).

I know (old) computers where pointers are hardware-typed, so you can't refer to an integer via pointer to float (and vice versa). Probably, on such computers C++ compiler (in theory) can generate a proper conversion code for reinterpret_cast (but not for unions, of course). A very good compiler is capable to generate a proper run-time check up of a good object alignment (in debug mode, for example) for reinterpret_cast - and so on.

Apropos, reinterpret_cast for pointers has C++-defined result only if you previously assigned a pointer value to void* then reinterpret_cast this void* value to the same type!

Moral: use reinterpret_cast where possible, but a trick is a trick...

Alex Edwards commented: Thank you! =) +3
ArkM 1,090 Postaholic

Don't worry, it's not so hard. Look at, for example:
http://www.parashift.com/c++-faq-lite/serialization.html
http://www.functionx.com/cpp/articles/serialization.htm
Better think about your class design defects:
1. You have char id_no[5] member then call strcpy(id_no, id) in the constructor. What happens if strlen(id) > 4 ? Right, you overwrite your memory and get a crash or bad data or undefined behaviour (or all three trubles together).
2. You allocate a memory for name by hands (without check up if n_p parameter is 0) then use strcpy to fill it. Why? You include <string> header in the program - use it! Try to declare all text variables in your program as std::string (it's possible and comfort solution in that case).
3. Make obvious "getter" member functions inline (declare them in the class declaration body):

class Aluno
{
  protected:
	 std::string id_no; //char   id_no[5];
	 std::string nome; //char * nome;
	 static int numero_Alunos;

  public:
          // add const modifier:
	 Aluno(const char id[], const char* n_p);
          // add for your convinience:
                 Aluno(const std::string& id, const std::string& nom):
                        id_no(id), nome(nom)
                 {}
	 ~Aluno(); // may be trivial in that case.
	 const char * Get_Id() const { return id_no.c_str(); }
	 const char * Get_Nome() const 
                 {
                       return nome.c_str(); 
                 }
	 static int Total_Alunos()
                 {
                       return Aluno::numero_Alunas;
                 }
};
ArkM 1,090 Postaholic

Aha, it's natural that the parent is an abstract class so no need to pass him any parameters. Slightly clumsy interface, usual way to declare such interfaces is:

class Field {
public:
    virtual ~Field() {} // sic! Add null virtual destructor    
    virtual void display() = 0;
    virtual int edit() = 0;
    virtual bool editable() const = 0;
    virtual void *data() = 0;
    virtual Field *clone() const = 0;
};

About clone: it's so simple:

return new LField(*this); // You have copy constructor!

About three in one: there was misprinting in my post above, copy/past then implement the constructor:

LField(int row, int col, int width, char *s = 0, bool editable = true);

There are tons of links about default arguments in C++ functions. For example (randomly selected):
http://msdn.microsoft.com/en-us/library/91563f79(VS.80).aspx
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc07cplr237.htm
You can write:

LField(1,2,3)           //  LField(1,2,3,0,true) called
LField(1,2,3,"Ooh")  //  LField(1,2,3,"Ooh",true) called
LField(1,2,3,"Zoo",false) //

That's all. I'm off-line now...
Good luck!

ArkM 1,090 Postaholic

Truth to tell, it's a very strange code.
About 11 employees: of course, the loop for (i = 0; vendedor.legajo!=0, i <= 10; i++) repeats 11 times. Take a piece of paper and a pencil... Right: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;)...
If you want to process 10 employees, where is an array of 10 struct datos_vendedor?
Do you think that you wrote well structured program if your main function body is so "functional":

ingresar_legajo ();    // function to enter the code	
comparar_datos ();   // function to compare the max sales made

?
No, these functions process global data and the reader does not know what they do. Declare processed data in main body then pass them to these functions as arguments.
Please, forget global data declarations as soon as possible: no need in this senseless data globalization...

ArkM 1,090 Postaholic

To judge from appearances:
1. The class destructor is not virtual (see requirements)
2. The class constructors do not pass parameters to the parent class (why?). It's interesting to look at the parent class declaration too...
3. No need in public initialize() member function, make it private (or protected). You have the same check parameters sequences in all constructors. May be better move these codes in initialize() or (more better) use default arguments to declare one and only one constructor:

LField(int row, int col, int width, char *s = 0, bool editable = 0);

4. Some misprintings (for example, in the line #120).
5. Max row check is wrong (must be >= ).
6. Style: better place all privates in the bottom of class declaration with explicit private keyword. Always declare one member per line.

ArkM 1,090 Postaholic

Regrettably, sonicmas can't follow williamhemsworth's advice without serious troubles: it's a big mistake to save Pessoa class objects as binaries with proposed SaveStruct template!

ArkM 1,090 Postaholic

Have you ever seen any C++ syntax description?
There are tons of syntax and semantics errors and wrong names in your source.
1. endl is ENDL, not END-one.
2. Add semicolon after names declaration.
3. Delete semicolon after main header (write int main() without old-fashioned (void) ).
4. Insert << in output statements (some occurences).
5. if header syntax: if (expression) , insert missed parenthesis.
6. Declare undeclared variables.

Ooh! It's not all...
Do it yourself then come back...

ArkM 1,090 Postaholic

May be, TBS constructor is not so long? If the program crashed in new TBS() then let's look at TBS::TBS()...

ArkM 1,090 Postaholic

For vectors and valarrays iterators do not provide any advantages (except more cumbersome codes - if you get pay for every LOC, of course).
So this supposedly C-style operator [] is much more natural vector accessor...

ArkM 1,090 Postaholic

1. You can't COMPILE this snippet: no such API function as creatThread.
2. Your thread do nothing. It starts then dye in silence. What TBS.TbbStart() doing?
What's a true problem?
Obviously, insufficient info...

ArkM 1,090 Postaholic

Use std::ostringstream class (from <sstream> header) and its member function str().
It's so simple ;)..

ArkM 1,090 Postaholic

There are at least two mistakes in your va_list using:
1. Don't use va_start macros in util_func: this function gets va_list argument ready to use.
2. Every va_arg call modifies va_list variable, so battleShip() passes wrong va_list value to util_func. Possible correction:

void battleShip(int n, ...)
{
     va_list p;
     va_start(p,n);
     va_list q = p;
     ....
     util_func(n,q);
     va_end(p);
}

Warning: variable argument list is a very dangerous (error prone) method. Don't become mad about it...