Banfa 597 Posting Pro Featured Poster

Cowandchicken??

If you mean was that string tailored to the code after I had examined it then yes.

However there is a serious but generalised point here, if the validation does not validate the exact format, with allowable variations, then you let in the possibility that the user manages to type in something that was actually meant to go in a different field but somehow manages to conform loose verification of the field they have typed into the program has unwittingly let in incorrect input.

If the software is in everyday use then the chances of this happening go up and if for some strange reason the cancel input function of the software doesn't work and the software acts on the input even if cancelled they it could be a disaster (don't laugh I've seen it happen).

Not checking that there are no invalid characters between the end of the parsed input and the next separator is sloppy.

Banfa 597 Posting Pro Featured Poster

No I am saying if the value passed in the parameter is irrelivant to the operation of the function then it shouldn't be a parameter in the first place.

Nothing to do with the function return value.

Banfa 597 Posting Pro Featured Poster

I agree and it wasn't so I (or may be Tech E) got lucky :D

I certainly wouldn't have gone hunting for it in that much code without help.

Banfa 597 Posting Pro Featured Poster

Also you may just wish to consider making some of those function parameters just local variable to the function for example

double radius(double X,double Y,double secX,double secY,double R)
{ R=sqrt(pow(X-secX,2)+pow(Y-secY,2));
return R;}

The value passed in using parameter R is never used, you overwrite R immediately. You are needlessly pass the parameter. This is most obvious at the top level in main where you pass all the parameters to entire without initialising a single one.

This function code be written without parameter R as

double radius(double X,double Y,double secX,double secY)
{ double R=sqrt(pow(X-secX,2)+pow(Y-secY,2));
return R;}

Now it is obvious that R is redundant, correcting the formatting as well

double radius(double X,double Y,double secX,double secY)
{
    return sqrt(pow(X-secX,2)+pow(Y-secY,2));
}

Also note that this is now exactly the same as your distance function. That is logical because the distance from the centre of a circle to a point on its circumference is the radius of the circle.

Banfa 597 Posting Pro Featured Poster

With thanks to Firefox for its ability to highlight the word salary

Line 27 of Income Member Function Definitions salary += s; You add the user input value s to salary but salary has not been initialised to anything and contains garbage therefore

garbage in = garbage out

Banfa 597 Posting Pro Featured Poster

1. The constructor is for exactly what you have stated "initialize variables or assign dynamic memory". In this case there is no dynamic memory so it is for initialisation of member variables. If you don't implement the constructor then between constructing the object and calling read() your object will contain garbage. You use the constructor to initialise the member variables to some zero state.

2. "const Polynomial10& pol" - that is a constant reference to a Polynomial10 object. References have some similarities with pointers (what you learnt pointers yet?). Some differences are

  • A reference must be initialised so you can not have a NULL reference like you can have a NULL pointer. It also makes it quite a lot harder (but not impossible) to have an invalid reference where as producing an invalid pointer is quite easy. They are considered to be safer than pointers.

  • Once assigned a reference can not be change to reference a different object. All operations on a reference are operations on the object it references.
  • References use the member access operator . not the pointer to member access operator ->

The const is important to, it means that the function called is guaranteeing not to change the object that being reference.

gnarlyskim commented: very informative and helpful +1
Banfa 597 Posting Pro Featured Poster

I have been programming for 20 years and I can say I've missed the absence of a Logical XOR operator where as I know for a fact I would miss the absence of a Bitwise XOR operator.

Banfa 597 Posting Pro Featured Poster

I would say use vector<bool> instead of your array however vector<bool> is not a standard vector and that may cause issues.

However I notice that rather than assigning true or false you always assign 1 or 0 to your array elements which means you could just as easily use int (or char if you are space concious) as vector<int> line; You would need to size the vector before using it but then if you had vector<int> line2; you could just do this line = line2; And you could still access the vector as if it was an array using the [] operator.

Generally when using C++ using vector rather than arrays should be preferred.

Banfa 597 Posting Pro Featured Poster

int * array = malloc(sizeof(int)); But my HOME COMPILER flags it as an error. But ideally, neither of them shouldn't say anything. Why this anomaly?

Most likely you are accidentally compiling it as C++ code at home, what compiler are you using and what is the exact name of the file?

Banfa 597 Posting Pro Featured Poster

3. Line 51 NEVER, EVER, EVER, NEVER recursively call main().

Just to expand this statement a little and say that calling main in C++ is expressly forbidden by the standard and some compilers will produce an error.

That is one of the many differences between C and C++, calling main in C is not forbidden but is still quite a bad idea.

Banfa 597 Posting Pro Featured Poster

Create a structure (or a class) that contains your string and double and then make a vector of those.

You can use a normal loop or one of the stl algorithms to perform operations on it.

Banfa 597 Posting Pro Featured Poster

max_element has 2 forums, one compares elements automatically using the < the other accepts a comparison function as well as the 2 iterators.

Therefore either you need to put an operator< method into your structure or you need to provide a comparison function and use the second forum.

In this case I would opt for using a comparison function because operator< has no proper symantic meaning for your structure.

See max_element reference

Banfa 597 Posting Pro Featured Poster

before trying to implement eliminating lifelines I think you code is in desperate need to refactoring to put common code in functions that can be called.

For example:

A function that asks the question
Parameters:
The question
The 4 answers
The right answer
Returns a flag indicating if the question was answered correctly

A function that asks for a lifelline number
No parameters
Returns the number of a valid and available lifeline

Banfa 597 Posting Pro Featured Poster

How does it respond to shar turns, what is its behaviour.

You might want to start erring on the side of giving too much information rather than too little.

Banfa 597 Posting Pro Featured Poster

Always keeping as much precision as possible is definately not a bad option, however there are others.

For instance there is no point in keeping 15 decimal places of precision if the value represents a real world item with a fixed quantum of precision, for example cash. I can have £6.349999 because cash is not available in that quantum, I must have either £6.34 or £6.35.

The problem is I see cash as having decimal places and force that perception onto the computer where it does not need it. Instead of holding the value in pounds I can hold it in pence, 635p as an integer. Now the physical limit on the quantum change of the value is matched by the computers limit on the quantum change of the variable, 1 in both cases.

Back to the original problem. You are holding a percentage as an integer and want it rounded off to 1 decimal place. Everyone is saying use a float and perform werid calculations to try to round it that are bound to not work quite correctly at some point due to the non-exact nature of floats.

Why not hold it in an integer in units of 1/10 of 1%?

I am not saying this is the right way. That is dependent on your program. What I am saying is if you really want to limit the number of decimal places you are using this is the way to do it. However if …

Banfa 597 Posting Pro Featured Poster

How is y declared?
You should perhaps check cin to make sure that no error has occured on it.

Banfa 597 Posting Pro Featured Poster

Look up the library function strtol, it will convert the digits ignoring leading blank spaces and pass a pointer back to where it finished, which will be the '/', you can then just hop over the '/' to convert the next piece of the number.

Banfa 597 Posting Pro Featured Poster

Almost everywhere you have a loop and access your arrays you have an out of bounds array access, for line declared as

bool line[78];

then if it is accessed as line[N] N must conform to the constraint 0 <= N < 78

However

void firstline(bool firstline[])
{
	int y;
        for(y = 0; y <= 78; y++)
        {
                if(y != 38)
                firstline[y] = 0;

y can be 78 - out of bounds

void coutline(bool coutline[])
{
	int z;
        for(z = 0; z <= 78; z++)
        {
                if(coutline[z] == 0)

z can be 78 - out of bounds

void rules (bool rules[])
//Put line in and follow 8 rules
// Rule: 1   2   3   4   5   6   7   8
//      111 110 101 100 011 010 001 000
//       0   0   1   1   1   1   0   0
{
	int x;
	bool nextLine[78];
	for (x=1; x < 78; x++)
	{
		//rule 1
		if (rules[x-1] == 1 && rules[x] == 1 && rules[x+1] == 1)
			nextLine[x] = 0;

x+1 can be 78 - out of bounds

Also it is bad practice to litter your code with the magic value 78 when in call cases that value has the same semantic meaning, width of the pattern being created. declare a const int at the top of the file with a good semantic name and use that, then if the width of your pattern changes you only have to change 1 place.

Banfa 597 Posting Pro Featured Poster

Not for template functions (and classes).

A template function are the instructions to the compiler on how to write the function given the parameter types... the template of the function.

When the compiler compiles your code and sees a call to a template function it looks up the template function and uses it to create an actual function that it compiles into the object for the file.

However the compiler works on a single file at a time. If the template function is not defined somewhere in the file being compiled the compiler can not create a real function from the template when it sees the function call because it can not see the template.

So the definition of the template function needs to be visible to the compiler when it is compiling your file there are 2 ways of doing this

  1. Put the definitions of the template functions in the header.

  2. Put the definitions of the template functions in a different file, NOTE not a cpp file because best practice is not to include cpp files, and then include that file into the header.

Whatever you do at the time the compiler sees the template function call it must have already seen the definition of the template.

hkBattousai commented: Thank you for the explanation. +4
Banfa 597 Posting Pro Featured Poster

P.S. and Off Topic

Count 1 Result: 1418854
Count 89 Result: 8581146

Banfa 597 Posting Pro Featured Poster

And what does that program do when the bot handle respectively

1.It has to follow white line track on the black background.
2.It should has high speed.
3. The path has intersection, curve turns, sharp turns (60 degree turn), discontinuities.

Does it handle them correctly or does it do something undesireable?

Banfa 597 Posting Pro Featured Poster

I am not seeing anything obviously wrong. When you are cerating the class objects I assume max is not 0, that would cause this behaviour.

I would suggest modifying Course::generateClassList, at least temporarily to output max so you can be sure it is good.

You have something strange going on between lines 83 - 81 with c_next which appears to be a redundent variable.

I would try stepping through Wrapper::fillCourses in a debugger if there is no problem with max.

Banfa 597 Posting Pro Featured Poster

For example, If you return a constant reference for the += operator, then you are allowed to do this :

Actually no, if operator+= returns const & then you can't do line 6 at all because the second += trys to modify the result of the first += which it can't because that value is constant.

Line 5 is only valid if getX is declared as const.

This is exactly the behaviour you want operator+= returns a value that can be used but not modified, or more simply it returns a value. The caller can copy the value if they choose into there own object and then modify it.

This is also exactly the semantics displayed by += when you use it with an int

int fi = 0;
    int gi = int(1);
    int hi = int(2);

    cout << (fi += gi) << endl;
    cout << (((fi += gi) += hi)) << endl;

I have just changed foo to int from you code. This compiles, even line 6. However line 6 in undefined behaviour and should be avoided, with the object line 6 wouldn't compile which is probably better than accidentally introducing undefined behaviour.

The reason for returning a reference in this and similar cases is that it is much more efficient than returning an object which entails object copying and possibly the creation of temporary nameless objects that have to be deleted again.

So the point is that by returning const reference, and …

Banfa 597 Posting Pro Featured Poster

Put in a cout statement as the first line of your function

void array_merge (int * array, int low, int high, int mid)

output low, high and mid. I think you will find that sometimes high has a value of 5. That tarnslates to j have a value of 5 sometimes and that translates to an out of bounds access into array because array has a size of 5 which means valid indexes are in the range 0 - 4.

I think this stems from the original call to sort_merge on line 80 using size_of_array.

Banfa 597 Posting Pro Featured Poster

Line 11 loanDurationon is defined without giving it an initial value

Line 29 the code what would have given loanDurationon its initial value is commented out

Line 32 loanDurationon is used in a calculation having nenver been given a value because line 29 is commented out.


You need to assign a value to loanDurationon before execution reaches line 32.

Banfa 597 Posting Pro Featured Poster

is the .C or .c? gcc defaults to C++ compilation for .C

If you want c compilation rename all your source files to .c or put

-x c

on the gcc command line which forces c compilation. I recommend the first.

I use the following compilers and IDEs and editors

At Home
gcc 4.4.1
Eclipse
Code::Blocks

At Work
gcc 4.2.4
MinGW 3.4.1
Visual Studio 2008 Express (compiler and IDE)
Eclipse
Geany
Notepad++

Banfa 597 Posting Pro Featured Poster

I did not mean operator=, I surely would have said that if I meant it and in fact because of the nature of operator= and operator+= they would return the same type, both const references because the return the object that was assigned to.

You can't return a reference from operator+ because you are not returning either of the arguments but an complete different value, the result of adding the 2 arguments. That requires a new object that is created inside operator+.

This object could have 1 of 2 scopes, automatic (on the stack in most implementations) or allocated (on the heap in most implementations. Considering each case in turn for a generic type T

automatic variable (on the stack)

const T& operator+(const T& lhs, const T& rhs)
{
    T result;
    result = ... ; // Actual calculation of lhs + rhs however it applys to T
    return result;
}

The problem here is that result has automatic scope, as soon as operator+ returns it is destroyed. However you returned a reference to it not you have an invalid reference waiting to cause havoc in your program.

allocated variable (on the heap)

const T& operator+(const T& lhs, const T& rhs)
{
    T* result = new T;
    *result = ... ; // Actual calculation of lhs + rhs however it applys to T
    return *result;
}

OK now the result object exists beyond the lifetime of the call to operator+, the reference returned will be …

Banfa 597 Posting Pro Featured Poster

The Visual C++ compiler is near Standard C++ compliant. The only things I am aware of it not doing are full support for exception lists and it has a little problem with really complex template notations used as friends.

Microsoft C++ does have some extensions to C++ however I did not think these should prevent Standard C++ from compiling. However if you do not want to use the Microsoft extensions there is an option in the project to disable Microsoft Extensions. Selecting that should make the Microsoft C++ compiler as standard compliant as it is capable of being.

Banfa 597 Posting Pro Featured Poster

ships is declared as an array of pointers but on both lines 17 and 23 having selected the array index you dereference the array once with * and once with -> or twice in total.

You can dereference a single pointer twice, loose the * on both lines.


BTW I suspect you want the derived class mutators to call the base class mutator as part of their operation.

Banfa 597 Posting Pro Featured Poster

The cout code needs to be inside the braces for displayOctal

Banfa 597 Posting Pro Featured Poster

This is probably wrong.

Did it compile?

BTW see FBody's post because I think he is right. It didn't occur to me because after 20 years of programming I am now phsycologically trained to void using a pen and paper where ever possible.

Banfa 597 Posting Pro Featured Poster

n

Banfa 597 Posting Pro Featured Poster

I don't get this error. I mean if i try to free a NULL memory, it does not say anything.

That might be a feature of your plaform, and the fact you are compiling as C++.

C++ does allow

delete 0;

explicitly in the standard.


If free is calling the same underlying system routine it may be able to cope with free(0).

However the other option is that you have invoked undefined behaviour and at some random time in the future your program will stop working for no apparent reason. Is that what you want to happen?

A C program must avoid freeing 0.

Banfa 597 Posting Pro Featured Poster

This was another one of my doubts. If i don't type caste calloc/malloc, my compiler is giving me errors. Take a look

Then you are compiling your code as C++. C++ and C handle the void pointer diferently in C void* can be implicitly cast to any other pointer type but in C++ all pointer casts must be explicit.

I have a feeling that I might think that writing C code and compiling it as C++ is a bad idea. That is if you are going to compile as C++ then write C++ code taking advantage of its features and library, such as the std::vector.

Banfa 597 Posting Pro Featured Poster

cout << "FunctionName: parameter1 = " << <parameter1> << endl;

as the first line of the function or as I said use cerr instead of cout.

Banfa 597 Posting Pro Featured Poster

Yeah I think it definately means produce a list of how the function is called.

Basically each time displayOctal is called output a line saying its been called and what parameters its been called with so that you trace the operation of the function. <----- still a guess if this is course work check with your professor.

Tracing might also included outputing the functions return value, but this function doesn't have 1.

The trace should provide enough information so that you can follow the exact path through the code that execution has taken.

100 is the intial value to call displayOctal with.

If you output your trace to cerr you can split the proper function output and the trace output.

Banfa 597 Posting Pro Featured Poster

what is wrong with

cout << oct << n;

?


In this context trace is ambiguous. I would have thought it meant that you need to output what the function is doing on each iteration.

And finally n is not a decimal number if you insist on assigning it a base then binary would be most appropriate as you are (probably) working on a binary computer, however the best approach is to not think of it has having a base at all until you try to display it to the user, that is base is a property of how the value is displayed and manipulated not of the value itself.

Banfa 597 Posting Pro Featured Poster

Line 49 of the new listing, only free array if array is not NULL or you willl get a run time error.

This is correct

int *array = (int *)calloc(<NumberOfItems>,sizeof(int));

although I personally would not cast the return value of calloc so I would write

int *array = calloc(<NumberOfItems>,sizeof(int));

Casting the return value causes problems if your code needs to be portable or work on 64bit systems and you have failed to include stdlib.h. If you have included stdlib.h it's all a bit moot but I think it looks neater without the cast.

Of course in C++ you can call malloc/calloc without casting the return value but then you should be using new anyway.

c-faq - whats wrong with casting malloc

Banfa 597 Posting Pro Featured Poster

It can be good to return references to objects when you can, for instance the return from operator+= can be a reference.

It is not possible to implement operator+ returning a reference and correctly handle memory.

Banfa 597 Posting Pro Featured Poster

Your first error is, I think, because you have declared LENGTH with automatic scope. That is it is on the stack, since it is on the stack and gets created when the function is entered it is not a true constant but a variable and so can't be used for array declaration.

try declaring LENGTH static or at global scope.

Errors 2 and 3 are a direct consequence of error 1, ignore them if you fix 1 they will go away.

Error 4, you have "Y" in the if statment instead of 'Y'. You have 'y' correct already.

Banfa 597 Posting Pro Featured Poster

you have a potential error in case #1.

No there isn't.

You are asking calloc to give memory of some number * the size of an int. But you don't want the size of an int, you want the size of an int * (pointer).

True but not relevent.

If you are allocating memory for an array of int's then use sizeof(int), but if you are allocating memory for an array of pointers to int, then use sizeof(int *).

Also true and not relevent.

Since you are casting the result to an int *, it should be an int * in the sizeof(), not int.

You are wrong on this point (which is why your other points are not relevent). The variable array is of type int * which is why the output of calloc is cast to int *. array is pointing to an array of ints it is easy to determine ask yourself what the type of array[0] is (or *array). It is int that is the type of the elements of the array. It it was an array of int * then array would have to be declared int **.

Since it is an array of int the size in calloc should be sizeof(int). This also works out with what the return is cast to, because there should be a single dereference level difference between the return type cast and the size of the type calloc'd.

For any generalised type T callocing …

Banfa 597 Posting Pro Featured Poster

Why can't you make a new object in the function and return it? Because you are returning const Text&?

That is the mistake, you can't implement operator+ returning a reference, it has to return an object so the prototype for your operator+ should be

const Text operator+(const Text &) const

and then you can create a new object and return it.

If you can lay your hands on More Effective C++ by Scott Meyers look up Item 20 which explains this in depth.

Banfa 597 Posting Pro Featured Poster

I can't explain why it is working at home, but that is the nature of undefined behaviour, however at line 48 of your code listing you free the array just before you start writing values into it.

mitrmkar commented: ... the nature of undefined behaviour +5
Banfa 597 Posting Pro Featured Poster

No if you take your lib you will be fine.

If you took your header file in its original form with no C file and no lib then you would get the error I described.

Banfa 597 Posting Pro Featured Poster

What hasn't been mentioned yet is if you left the function defined in the header file and then included that header into 2 C files in a project and tried to compile and link those 2 files you would get a "symbol defined multiple times" error from the linker because the function that is in the header would be present in both object files when you try to link them and the linker is unable to determine which one of the 2 functions to use.

Every function must appear in a program precisely 1 time. For that reason you must avoid putting functions in headers and for the same reason you must avoid defining variables in headers.

Banfa 597 Posting Pro Featured Poster

I think you will find it very hard to code this sorting algorithm as anything other than single threaded. The problem is that every phase of your algorithm depends on the previous phase so no phase can be done independently of any other.

If you want to use multiple threads for sorting you will need to choose an algorithm that is suited to rather than the simple sort you appear to be using. For example a merge sort that sorts a list by recursively into 2 lists sorting each of those lists and then merging the 2 sorted lists back into 1.

Sorting the 2 halfs of a list could easily be done by 2 threads.

Merge sort is by no means the only algorithm that leads itself to multiple threads in this manor.

Banfa 597 Posting Pro Featured Poster

Hmmm the only real way to know you have the right data is to compare it to the original. You could printf the data but then you would have to look inside the original file using something like a hexeditor and see if it was right. That could be a long job on a large file.

An easier method might be to write the data back out to a ne file in the original format. Then you can use a 3rd party file comparison program to compare the old and new files. If you have read and written the the data correctly the 2 files should have no differences.

Banfa 597 Posting Pro Featured Poster

All your #defines have a ; at the end of them which will be prducing invalid syntax, remember a #define is a text substitution.

Also you should note define functions, like snapwrite, in a header. You should declare the function in the header

int snapwrite(char *_symbol, int _typeval, char *_val);

and define the function in a C file somewhere.