Banfa 597 Posting Pro Featured Poster

Youve missed to top of your code

  1. The easiest way to put a repeat into a game once it is already working is to move the whole game into a function, then add your loop that askes the user if they want to repeat in main and call the function. A do ... while loop works well for this since you always want to play the first game.

  2. I'm slightly surprised that the loop at line 31 doesn't just do into an infinite loop when you guess a letter that is in the word. Line 34 - 36 actually replace a single correctly guessed letter in the word and are only done once for each letter guessed.

You code could use a proper refactor it is messy and confusing. I can tell this because the lines

    //Prompt the user to guess a character in the word.
    cout << "(Guess) Enter a letter in word " << word << " > ";
    cin >> letter;

Appear 3 times in your code. This should not be required, this program can easil be written with the guess request in only 1 place (I would say just inside the do ... while loop. The only other loop required would be to look for multiple occurances of the same letter that was guessed.

Banfa 597 Posting Pro Featured Poster

Wrapper classes don't have to encapsulate another class, they can for instance encapsulte a legacy C interface or in your case a propriatory interface to some board.

If you are trying to implement the same wrapper interface for 2 different boards it is worth using an interface class so that the majority of you code just deals with the common interface.

class Interface
{
public:
  virtual ~Interface(){} // Virtual destructor for class designed as a base

  virtual int initialiseBoard() = 0;

  virtual int setRegister(int register, unsigned value) = 0;
}

class Fona : public Interface
{
public:
  Fona();

  virtual ~Fona();

  virtual int initialiseBoard();

  virtual int setRegister(int register, unsigned value);
}

int Fona::initialiseBoard()
{
  int result = 0;
  // Code to send initialisation parameters and commands to the board

  return result;
}

All you code can deal with the Interface class via references and pointers you instantiate the classes you need (possibly using a factory class or function).

However having seen the 2 boards you want to interface to, a GSM module and an FM radio it seems to me that their interfaces may have little in common but I haven't actually checked the data sheets.

gadgets1010 commented: If they have little in common, does that make this task very difficult or does it make it impossible? +0
Banfa 597 Posting Pro Featured Poster

At line 19 and 20 you are using the symbols sys_nerr and sys_errlist but this is the first time the compiler has seen them, you have not previously declared them anywhere hence they are "undeclared".

You may have missed out a header file in which they are declared or you may have failed to write their declarations.

Banfa 597 Posting Pro Featured Poster

Line 54

template<class T >
T  display_array(T ItemType[10] , T const int arraySize)

This is invalid. Remeber that the compiler will substitude the type T in the template into the code provided in order to instatiate the function for you. You can do this by hand and should get the valid code. In this code if T is int (as is the case in main) then the code becomes

int  display_array(int ItemType[10] , int const int arraySize)

Hopefully it is obvious that the type of the 2nd parameter int const int is not valid. It should presumably be const int which would be removing the T from the beginning of the parameter type.

Line 59

cout << array1 << ' ' << arraySize;

array1 is not visible here, it is a local variable to main. Even if you changed it to ItemType, which is a valid local variable, you are just going to get an address (because ItemType is a pointer) or alternitively a compiler warning/error.

Line 66

 template<class T>


 streuct Item Type{
     int length;
     int array1[arraySize];
 }

You appear to be trying to declare struct ItemType, ignoring spelling an spaces you appear to be confusing type names and variable names. In various places in this code you use ItemType as a type name (here and top of main) or a variable name template at line 54. Also you have declared this structure as a template dependent on type T and …

Banfa 597 Posting Pro Featured Poster

My compiler does not support scanf_s (it's a Microsoft extension I think) but if I change your scanf_s to a scanf call it works as expected.

So I looked up scanf_s in the Microsoft help and it said

Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if you are reading a string, the buffer size for that string is passed as follows:

and then gave this example of reading a char

char c;
scanf_s("%c", &c, 1);

Next time try reading the manual.

ddanbe commented: Great! +15
Banfa 597 Posting Pro Featured Poster

Actually since this is C and the structures are also in an array you could just use qsort to sort them.

Banfa 597 Posting Pro Featured Poster

You have a few small problems but the one causing the error you are seeing is in Queue<ItemType>::Enqueue, if rear is NULL you set front but you do not set rear so the next time you enter this function rear is still NULL and you just overwrite front, incidentally causing a memory leak, and not actually setting up a queue.

Other errors

size is not set in the copy constructor

In Queue<ItemType>::Dequeue you don't set x

You have multiple unnecessary ; after every function definition.

And finally: in Queue<ItemType>::Dequeue you decrement size regardless of if you actually deleted an item from the queue which means if called on an empty queue it goes negative and gets out of step with the actual queue size.

Banfa 597 Posting Pro Featured Poster

That is because you only have 1 buffer, buff. At line 13 all you do is store a pointer to buff in the array token so all entries in token end up pointing an the same buffer, buff and when you print out your tokens they all contain the same thing, the last thing you entered, because they are literally pointing at the same object.

change the declaration of token to char token[20][20]; and strcpy from buff into token (or just get rid of buff altogether.

Banfa 597 Posting Pro Featured Poster

Your problem is between lines 23 - 31. You get 3 numbers from the user but you only use 1 variable so everytime you overwrite the previous number that the user input. Then at line 31 you push a single value, the last onbe entered, onto the stack. This comment // PUSH NUMBERS ON STACK at line 30 is distinctly confusing because it is not what the code is doing at all.

You need to push the value onto the stack after each time the user enters it.

Banfa 597 Posting Pro Featured Poster

Line 11 argv[i] = malloc(sizeof(temp)); or the modified form argv[i] = malloc(sizeof(temp+1)); does not allocate enough memory.

temp is a char* and has a fixed size 4 bytes (or maybe 8 depending on platform) so these 2 lines respectively allocate either 4 or 5 bytes of data. You then strcpy what temp points to into the location pointed to by argv[i]. This is likely to be a larger copy than the allocated memory.

You need to allocate memory for what temp points to not temp itself, the easiest (if not most secure) way is to use strlen and add 1 for the terminator.

argv[i] = malloc(strlen(temp)+1);
Ancient Dragon commented: Right :) +14
Banfa 597 Posting Pro Featured Poster

Char "is a simbol" found in ASCII code.

Not really, ASCII is a way of encoding alaphbetic (and other) symbols as a number and defines numbers in the range 0 - 255. And a char is an integer data type.

All characters can be converted into numbers in range 0-255, that's why is char 1 byte in size (2 to the power of 8 = 256).

Even more wrong, not all characters (in the world) can be converted into a number in the range 0 - 255 which is why Unicode, UTF-8, UTF-16, UTF-32 (methods of encoding characters like ASCII is) and wchar_t (wide character type like char is the single character type) exist.

char and int are both integer types each have several properties unique to themselves

char
signedness: if a char is signed or unsigned is platform dependent. it is usual to consider char, signed char and unsigned char as 3 distint types. Where as int is always signed and synonymous with signed int

trap bits: a char may not have trap bits it's value is an exact representation of the memory that contains it. In addition in an array of char, or incrementing a char pointer the individual char values obtained are required to be contiguous in memory. Neither of these are true of any other integer type, they may contain trap bits and do not have to be absolutely contiguous in memory means that if you want an exact view of …

mike_2000_17 commented: Very complete! +14
Banfa 597 Posting Pro Featured Poster

When you type in that letter at line 9 cin enters an error state because it can not complete the requested operation, input a number. Additionally the letter you typed is left in the input buffer.

This means that at line 25 cin is still in an error state because you have not cleared it so it automatically fails. If you did clear the error it would still not enter the loop because the letter is still in the input buffer and it would immediately fail again at the operation read a number and put cin back into an error state.

Just inputing a letter when your program is expecting a number is not a good way to indicate the end of data you need a better strategy for reading data from the using for example

  • Sentinal Value: the list is finished when the user inputs a specific sentinal value, 0 or -1 are common ones. Any other value gets put in the list
  • After each value has been input ask if there is another value
  • Before asking for any values ask the user how many values they wish to input
  • Read the input as text, if it is a string of digits convert to a number otherwise end the loop

There are probably other strategies those are just what I can think of off the top of my head.

Banfa 597 Posting Pro Featured Poster

Seems we tend to get most irrate at the things we know and therefore stand out most to us as being wrong. A friend of mine who had been a train driver used to get excptionally irrate at how TV/movie trains react to things on the line vis-a-vis

a) There is a person/car/helicopter on the line head of the train you are driving should you:

  1. Lean on the horn and keep going
  2. Apply the breaks and attempt to stop before you hit the obstacle

b) The train you are driving unfortunately has just hit a person/car/helicopter do you:

  1. Keep going or you will be late for your tea
  2. Stop call the emergancy services and start filling out the mile high stack of paper work that clearing up this mess is going to take

EDIT: Just to say that I actually had only read the first page before posting so someone may have already mentioned this in which case sorry :D

Banfa 597 Posting Pro Featured Poster

I think you have a problem at lines 2 and 3

//
for(a;a<sum;a++) {
    if(zaide[a] > 0) {

The initial expression at line 2 a looks wrong, did you mean a=0? Otherwise a is just forever getting bigger and you have not shown where you initialise a.

Then at 3 I think you have another array bounds problem. Again you have not supplied enough information to be sure but sum is being incremented in a manor that suggests it is going up quite quickly and if you remove the line incrementing sum your code works. sum going up allows the value of a to go up which could break the bounds of zaide.

Also strangly at line 6 you increment the value of a just before incrementing the value of a in the loop third expression.

Stuugie commented: Bam, I think you nailed that and I wish I saw it. +5
Banfa 597 Posting Pro Featured Poster

1 from the section of my website that I call "Poetry (sort of)"

The velociraptor of C++,
was talking to a poet thus:
the poet spoke, with some remorse,
“It's hard to fit your name in verse.”
The raptor to the poet said
“No it's not 'cos my name's Fred.
I see your error, you're confusing,
class and instance, how amusing.”

Banfa 597 Posting Pro Featured Poster

The question does not seem to preclude the use of a human processor so how about

#include <string>
#include <iostream>

int main()
{
  std::string text;
  std::string reversed;

  std::cout << "Please enter the string to reverse: " << std::flush;
  std::getline(std::cin, text);
  std::cout << std::endl;

  std::cout << "Please enter the reverse of \"" << text << "\": " << std::flush;
  std::getline(std::cin, reversed);
  std::cout << std::endl << std::endl;

  std::cout << "The reverse of \"" << text << "\" is \"" << reversed << "\"." << std::endl;

  return 0;
}

And let us not forget it does preclude any library so you could just std::reverse(text.begin(), text.end()); :D

rubberman commented: Great post Banfa! Nothing like leveraging stuff like the STL. +12
Banfa 597 Posting Pro Featured Poster

This is slightly stretching my, now 10 year out of date, recolection of WIN API programming but ...

I do not think GetStdHandle is likely to do what you want (with the caveat that of course I have no idea what you want so maybe it does) since it returns the standard handle for the current process but you want to set the stand output handle of your created process.

I seem to remember doing this by creating a pipe (CreatePipe) before creating the process and setting this as the std out handle in the STARTUPINFO structure passed to the process. Then you can read (and parse) the started applications output from the pipe.

Banfa 597 Posting Pro Featured Poster

Well you code compiles and links for me with exactly the commands you have given with the sole addition of #includes of cstdio and cstdlib to the top of your source files.

Also note that the array subscription operator has a higher preceedence than pointer indirection * so *A[j+i*N] is interpreted as as *(A[j+i*N]) which causes your program to exhibit undefined behaviour because I suspect you actually intended (*A)[j+i*N], which you can achieve by typing exactly that.

Banfa 597 Posting Pro Featured Poster

If you want to run a command in a command prompt you need to use the /c or /k switches before the command line, i.e. "C:\Windows\System32\cmd.exe /c ping google.co.uk"

Try cmd /? at a command prompt

Banfa 597 Posting Pro Featured Poster

There are a couple of negative implications.

Firstly if you compile and run a program on 1 machine that writes a structure directly to a file in binary form using something like fwrite and reads it using fread and then you try and compile and run the same programme on a different machine and use the file created on the first machine the second machine may not read it correctly because the different machines may have inserted different padding in different places and may, ultimately have different sizes for the structure.

The second issue is one of memory wastage. Obviously any padding in your structure is not used for anything, it is unused and unusable (unless you are doing something very very suspect with pointers). How you write your structure, the order in which you place the members can effect the amount of padding in the structure, OK only by a few bytes (probably) but if you then have an array of those structures that wastage is multiplied. Now this wastage may be meanless on todays multi-gigabyte memory machines but it can easily be significant on microprocessors with much smaller memory. I have had to deal with this very problem when an array of poorly written structures was using more memory than needed on a platform that was running low on memory. My re-ordering the members of the structure (and replacing a few ints being used as booleans with a bit mapped int) I was able to save 20 bytes …

ddanbe commented: Great! +15
Ancient Dragon commented: good post :) +14
Banfa 597 Posting Pro Featured Poster

Personally I would ignore "(a Big-Oh answer will do)" and give an exact answer. You have the formula for fine after n days

fine = 2^(2^(n-1))

The second question is how many days will it take to for the fine to reach D (i.e. when fine = D) all you have to do is re-arrange your equation to find n in terms of fine (logarithms will help here)

ln(fine) = (2^n-1)ln(2)
ln(fine) / ln(2) = 2^(n-1)
ln(ln(fine) / ln(2)) = (n-1)ln(2)

Giving

n = (ln(ln(fine) / ln(2)) / ln(2)) + 1

This is simpler to read if written in terms of log to base 2

n = log2(log2(fine)) + 1

If you really want your big O notation look at your original formula and notice you are using an exponential of an exponential of days so O(e ^ e ^ x), remembering that Big O notation is an indication of how quickly something gets big.

Banfa 597 Posting Pro Featured Poster

An arry variable does not "point" at anything, it is an array with assigned memory and the properties of an array. On of the properties of an array is that when its symbol is used without an index it decays to a pointer to the first item in the array. Another property of arrays is that you can't pass arrays by value, that is you can not pass an array to any function, you can only pass a pointer to the first item in the array (what is most commonly done along with the size of the array) or a pointer to the array itself.

void fn1(char *p)
{
  printf("fn1: %d %d\n", sizeof(p), sizeof(*p));
}

void fn2(char p[])
{
  printf("fn2: %d %d\n", sizeof(p), sizeof(*p));
}

void fn3(char p[5])
{
  printf("fn3: %d %d\n", sizeof(p), sizeof(*p));
}

void fn4(char (*p)[5])
{
  printf("fn5: %d %d\n", sizeof(p), sizeof(*p));
}

In fn1, fn2 and fn3 p has type char* because it is just a char pointer and the values printed are 4(because I am using a 32 bit system) and 1. in fn4 p has type char (*)[5] and sizeof p is 4 still, but sizeof *p is now 5 because p points to an array.

The point is that in a function parameter using [] instead of * means nothing to the compiler although programmers sometimes use the [] notation to indicate the function is expecting an array rather than a pointer to a single thing. Also note that there is no …

Banfa 597 Posting Pro Featured Poster

Think about what you are doing, inputing a 1 x 5 array of strings.

The first question is is that what you really meant because an array index with a size of 1 is quite odd and rarely used? For example this char i2DArray[1][5]; and this char i2DArray[5]; allocate exactly the same amount of data, 5 char. So were you trying for an array of 5 names or a matrix 1 x 5 also, as it happens, containing 5 names?

If the answer is an array of 5 names then what is a name? it's a string and what is a string? it's an array of char. Assuming that we can set a maximum size for a string containing a name, to say 50 characters, we could define a type for a name string

typedef char namestring[50];

If we want an array of those then it would look something like

namestring i2DArray[5];

This is a 2d array because namestring is an array, we can combine these to produce the array without using a typedef, subsitute i2DArray[5] into the typedef line in place of namestring and remove the typedef giving

char i2DArray[5][50];

If you actually wanted a matrix 1 x 5 of names the same argument applies and you would end up with

// 2 dimensional array of strings
namestring i2DArray[1][5];

// substitute i2DArray[1][5] into namestring typedef
char i2DArray[1][5][50];

a dimension for each dimension of the matrix plus one for the actual size …

Ancient Dragon commented: Excellent :) +14
Banfa 597 Posting Pro Featured Poster

Does it work? It prints "Inside A!!!" but does it print a number on the next line? If not then your program silently crashed.

It can get into A::func and print the first line (which is what my windows implementation does before reporting a crash at the next line) because up to that point it has not had to dereference this. It is only at line 13 when trying to access _dmember that it deferences this which is NULL and crashes.

This is all undefined behaviour so in theory it could run and print out you age (don't ask me how it got your age, the behaviour is undefined remember, it can do anything, perhaps it dialed into some government agency hacked their computers and got a copy of your birth certificate). The import thing to remember here is always avoid undefined behaviour, it's bad and it doesn't necessarily show up in testing, only after it has been deployed for 2 months.

Banfa 597 Posting Pro Featured Poster

This

pNResults.push_back(planetName());

for (i2 = 0; i2 <= cols; i2++)
{
    switch(i2)
    {
    case 1:
        pNResults.at(i).pName = string((char*)sqlite3_column_text(statement,i2));
        break;

    default:
        break;
    }
}

can be written more efficiently as

planetName planet;

if (cols >= 1)
{
    planet.pName = (char*)sqlite3_column_text(statement,1);
}

pNResults.push_back(planet);

it seems to me that the most likely problem is sqlite3_column_text returning NULL and you could modify this to check that

planetName planet;

if (cols >= 1)
{
    const char *data = (char*)sqlite3_column_text(statement,1);

    if (data != NULL)
    {
        planet.pName = data;
    }
    else
    {
        // report error
    }
}

pNResults.push_back(planet);

You should never just assume pointers are good.

If you implemented proper constructors, copy constructors and assignment operators for planetName then there are various other things you can do to simplfy your code.

This

for (i = 0; i < getCount("Planet_Names", bErrors); i++)
{
    ...
}

is very inefficient, every loop iteration you are querying the database store the result of getCount in a variable.

Use the debugger, it will show you where the crash is and by traversing the call stack you should be able to work out where the NULL pointer is.

Banfa 597 Posting Pro Featured Poster

The problem is your representation of the data (which of course then effects all your code). You have represented the data in the way you think about it as a human not in a way that makes it convienient to process has a computer.

BTW at least at line 26 if you mean the character '0' use the character '0' not the integer 48 because not all environements use the same execution character set and in some character sets the character '0' has a value other than 48.

So for demonstration purposes I am going to assume that NUM_DIGITS is 10

For -739 you hold the string "000000-739"
For -9871 tou hold the string "00000-9871"

You then add them character by character in reverse order and you add the carry at the wrong place, the carry is supposed to be carried over to the next column, you calculate the carry at line 42 and use it at line 47 but you should calculate it at line 42 and use it at line 41 and initialise it to 0 which you do do.

so
9 + 1 = result + carry
3 + 7 = result + carry
7 + 8 = result + carry
7 + 3 = result + carry
('-' - 48) + 9 = result + carry
0 + ('-' - 48) = result + carry
0 + 0 = result + carry
0 + 0 = result …

Banfa 597 Posting Pro Featured Poster

At anytime you think (while programming C++ (or C)) what would work here would be convert all my data to a string so I can interpret it you have made a design error. The computer handles binary data far better than string data the last thing you want to do is hold your data in strings if you can avoid it.

For the example you give with 2 small functions you are far better off using an if statement and then calling the right one of the 2 functions.

The refactoring I suggested in point 4 could be done with a function with the prototype of

int testMatrixCell(int x, int y,
        char cTrazeni,
        int (*Koordinat)[2],
        char cMatrixCellValue,
        int& xStart, int& yStart);
Banfa 597 Posting Pro Featured Poster

He doesn't have any choice but to use that formula, his instructor gave it to him.

Agreed, just don't get me started on instructors that set 1/2 baked questions that lead their students up the garden path :D

Banfa 597 Posting Pro Featured Poster

The way you have written Functions.h is more than something I don't like. The moment you start creating projects with more than 1 cpp file this approach will cause you errors because you will have multiple definitions of all the functions you have put into your header. Headers should only contain declarations it should not contain definitions. A declaration indicates that something exists where as a definition causes something to be brought into existance.

Example

Function declaration

int add(int a, int b);

Function definition

int add(int a, int b)
{
  return a + b;
}

The declaration in a header file included into multiple cpp files will not be a problem, it only states that a function exists, although it would need to exist in one of the cpp files. Put the definition in the header and it exists in all translation units (cpp files) that the header is included into and when you try to link all those translation units together you will get multiple definition errors.

FindStart
Why are you calling this from main and not from FindThePath? The user just wants to find the path they do not want to perform unnecessary initialisation. This function can easily be called from FindThePath, it has all the data, reducing the user to a single function call. Additionally the user does not then need to declare xStart and yStart which they casically have no interest in and if they really need can get from the …

Banfa 597 Posting Pro Featured Poster

You appear to be processing a file that contains a list of 1 line records. In you case the records are simple "<name> <number>" however I would always approch this by reading the entire record before processing it

while(Read Line From File = Success)
{
    Process Line
}

You could use fgets to read the line from the file but this does have the limitation that you need to know your maximum line size ahead of time. Alternatively you could create your own function that reads a line of any size using fgetc.

Again I would write a function to process the line once read spliting the processing of the data from the reading the data from a file. Then if at a later date you need to obtain the data from a different source, say a tcp/ip link, you can still use the same processing function.

Banfa 597 Posting Pro Featured Poster
  • Always use the double type not the float type unless you have a comunicable reason for needing to use float (like it's an embedded platformwithout much memory or the question you are answering specifies use of float).
  • Line 9 for(k=1;k<=n;k++) is poor form, you k is an unsigned type and n happens to be the max value for that type then what you have is an infinite loop. The more normal form to get n iterations is for(k=0;k<n;k++)
  • Line 22 while( (float)p-c>0.01||(float)c-p>0.01) no need to cast c or p to float, they are already floats also you are using math.h so make use of its functions while( fabs(p-c) > 0.01) (fabs returns the absolute value).
  • Line24, similar to 9, for(i=1;i<=j;i++) is poor form. The more normal form to get n iterations is for(i=0;i<j;i++)
  • Line 26 and 27 a=(rand()%10000+1)/1000; doesn't do what you think because it uses integer division. This means you get an integer result between 0 and 10 but I suspect you want a floating point result between 0.001 and 10.000. Since all the types in the formula are integers the compiler does the calculation as integers meaning the /1000 just chops off all the decimal places, if you want it to retain the decimal places you need to force the compiler to use floating point maths. The easiest way is to use floating point constants a=(rand()%10000+1.0F)/1000.0F;. Similarly for line 27. This is the problem as you squew the ration of points in a square to points in …
ddanbe commented: Great. +15
Banfa 597 Posting Pro Featured Poster

Code seems to work fine for me except that if there is not a new line at the end of the last number in the list your first loop produces a count that is 1 too small.

Banfa 597 Posting Pro Featured Poster

The problem is everywhere you new Node<TYPE>. The Node<Type> constructor does not set m_NextElement and everywhere you new it you don't set it either so in your list the final element in the list always has an invalid m_NextElement. When calling the list destructor this causes your program to exhibit undefined behaviour (in this case crash probably).

I would add a constructor to Node<Type> that initialised m_NextElement to NULL.

Banfa 597 Posting Pro Featured Poster

It is easiest to understand what << and >> do when you consider a number as a binary value (which is where convertion between binary and decimal come into it). This is because these are bitwise operators (2 of several), that is when they operate they consider individual bits of the operand rather than the overall number.

Considering just << (shift left) the operation is to shift the bits of the left hand operand left by the value of the right hand operand.

Considering the operation 10 << 2 the easiest way to understand what is happening is to consider the decimal value 10 in it's binary form 00001010b (I'm using 8 bits in this illustrantion but there would normally be more).

What happens is that all the digits in the binary representation are shifted (or moved) 2 places in the number to the left

00001010b --> 00001010xxb

The bottom 2 places are filled with 0

00001010xxb --> 0000101000b

And since this is an 8 bit number the top 2 digits are discarded

0000101000b --> 00101000b

And that is the answer converted back to decimal 00101000b = 40

Shift right is similar by the bits are shifted the other way 10 >> 2

Shift each digit 2 places to the right in the number discarding digits that fall off the right hand end

00001010b --> xx000010b

Fill in 0's at the left

xx000010b --> 00000010b

That's you answer the result is 00000010b = 2

The majority of processors have an …

Banfa 597 Posting Pro Featured Poster

Use fopen

Banfa 597 Posting Pro Featured Poster

Line 8 initialising b to 0 means that at line 9 you get a divide by zero error while trying to get the remainder after dividing a by b.

Banfa 597 Posting Pro Featured Poster

I assume you mean at line 11, that is because operator>> on an istream into a string uses any white space as a separator, it is specifically coded to only read up to the space. If you want to get an entire line into a string use std::getline, declared in string.

Banfa 597 Posting Pro Featured Poster

No there is only ever a single destructor

~a()
{
}

It never takes any parameters. This makes sense, the reason that you have parameterised constructors is that you may wish to initialise your object in several different ways, but when you destroy your object there is no need for any further data, you go from the current state of the object to no-object so the object already knows everything it needs in order to delete itself.

Banfa 597 Posting Pro Featured Poster

At line 14 you still have a and b declared as int but you scanf them as floats at line 16 which will produce the strange results you are seeing.

jandanielsaclolo commented: Fixed the code but it doesn't fixed the problem, It gives me 0.00 +0
Banfa 597 Posting Pro Featured Poster

Basically a floating point number is an approximation and if nothing else is specified then floating point constants have the type double.

This means that in the line float f2=14.385; the compile converted the double constant 14.385 to a float and then assigned it to f2; then in if(f2==14.385), since the compiler always converts to the largest type present for comparisons it converted the floating point value of f2 to a double, in the process of all that converting the compiler took an approximation that was not quite equal to the original 14.385 so the == returned false.

On my system it happened on float f2=14.385;

f2 ended with a value of 14.38500023 when converted back to a double.

Banfa 597 Posting Pro Featured Poster

The 'left to right' order you refer to is the operators associativity. This is nothing to do with what order the operands are evaluated in but is to do with the order multiple operators of the same preceedence are evaluated in, for example the left-to-right associativity of + and -, which have the same preceedence, means that a - b + c is evaluated as (a - b) + c and not a - (b + c) which would result in a completely different answer.

As Moschops points out the compiler is free to evaluate the 2 operands of any operator in any order it chooses with the exception of || and && which have to evaluate the left hand operand first to achieve short-circuit evaluation.

Banfa 597 Posting Pro Featured Poster

There are 2 things describing how/what order operators in an expression are evaluated; preceddence and associativity.

It is important to remeber that associativity is only ever applied to a series of operators of the same preceedence, that is in the line a = b + c; the associativity of the 2 operators, right-to-left for = and left-to-right for + do not come into play at all because = and + have different precences.

Preceedence only affects how the operands bind to the operators not the order in which the operators are evaluated; in A || B && C preceedence indicates that B and C will bind to && but the || operator is evaluated first.

Associativity defines the order in which operators are evaluated (and therefore sometimes how the operands bind to them) in a + b + c + has left-to-right associativity and therefore the left hand + is evauluated first and b binds to the first plus so it is equivilent to (a + b) + c.

A couple of operators, notably && and || have special rules (shortcut evauluation) which have to be taken into account when the order of evaulation is determined.

However that asside I believe there is no constraint on the compiler to evaulate in a specific order as long as it has satisfied the rules of precedence and associativty and the operators used; i.e. in a * b + c * d * has higher preceedence than + so this is evaulated as …

nitin1 commented: incredible post!! +2
Banfa 597 Posting Pro Featured Poster

As moschops said in a function

void function(int* p)
{
}

That has been passed some arbitary array then there is not way to know what the size of that array is from the passed parameter. Standard practice is to pass the array size in another function parameter

void function2(int* p, int size)
{
}

If you are not allowed to do that but you are using fixed size arrays then you could

Use a constant to define your array size

#define SIZE (5)

int array[SIZE];

void function3(int* p)
{
  int ix;

  for(ix=0; ix<SIZE; ix++)
  {
    p[ix] = ix;
  }
}

Or declare the function to take a point to an array of the right size

void function4(int (*p)[5])
{
  int count = sizeof(*p)/sizeof(int);
}
Banfa 597 Posting Pro Featured Poster

It wont do either it will cause undefined behaviour.

You must call free on the actually pointer value returned by malloc. If for some reason you need to increment the pointer you should use a copy so you can still free the original pointer.

int main ()
{
  int * buffer1;
  int * buffer2;
  buffer1 = malloc (100*sizeof(int));
  buffer2 = buffer1 + 5;

  free (buffer1);
  return 0;
}
Banfa 597 Posting Pro Featured Poster

Precedence is not about which operator is evaluated first, it is about how the operands bind to the operators.

So in the expression A || (B && C) the parentheses overide precedence, B and C bind to && and A and the result of the && bind to the ||.

In the expression A || B && C there are no parentheses to overide precedence, so in this case precedence takes effect an since && has a higher precedence the B and C bind to the && and A and the result of the && bind to the ||. Note this is the same as the previous example.

In the expression (A || B) && C the parentheses actually overide precedence. Normally the && having a higher precedence would use B as it's left hand side however because of the parentheses the A and B bind to || and the result of the || and C bind to the &&.

Again this is not about which operator gets evaluated first, they are evaluated as they are needed. This is about what each operator uses as its operands.

Banfa 597 Posting Pro Featured Poster

Reference variables are much like pointers, but you can declare them as const

You seem to imply that points can't be declared const, I'm not sure if that was your intention but pointers can be declared const just to clear up any confusion.

Banfa 597 Posting Pro Featured Poster

It only appears to work, it is in fact undefined behaviour, this is exactly what it says the behaviour may be a crash or it may appear to work or anything inbetween and it may do different things every time it is run. If you put this sort of code into a larger program that ran for longer you would run a very serious risk of the program crashing at some unknown point in the future.

And the moral: If you know it is wrong don't do it just because it "appears to work", do it the right way.

Banfa 597 Posting Pro Featured Poster

At line 107 you are missing the const on the declaration of the inclass parameter

Your declaration and definition of list_clear at lines 28 and 55 do not match

Banfa 597 Posting Pro Featured Poster

This sounds like it is a porblem caused by putting locks inside a loop without putting in anything that holds them up.

The thread reading from the socket should be held up by the socket comms, that is while it is not receiving any data it should not be trying to access the multimap.

Your main thread strictly has nothing to hold it up except that it only needs to process if there is something there to process. You need to use an extra object, a semaphore say. A semaphore is a sychronisation object that can be waited on that keeps a count, so every time the socket queue puts an entry in the multimap it posts to the semaphore and the main thread waits on the semaphore to be posted and then reads from the multimap.

Banfa 597 Posting Pro Featured Poster

The compiler error message either before of after that should give the line of you code that has produced this error. When posting compiler output post the complete output with the relevent lines of your source code.