Tom Gunn 1,164 Practically a Master Poster

I would say in order to give compilers more flexibility for generating the best possible machine code, but the spirit of your statement is on target. :)

Tom Gunn 1,164 Practically a Master Poster

It is all dependent on what conditions you use because in the case where you put it in the more common style yes there would be an error because you don't know what outer condition 1 is. But if you look at an example with real code if outer condition 1 is all of the inner conditions (1-4) then it works because you put return values for every case possible within that if statement.

Yes, so you understand the error now? Code with intertwined dependencies like this is bad code that needs to be fixed. If a maintenance programmer cannot glance at a simple algorithm and know that it is right without doing an in depth analysis, there is a serious problem.

Tom Gunn 1,164 Practically a Master Poster

Read what he posted not what you snipped.

I mean no offense, but you are wrong. Please study the code lancevo3 posted more carefully. I will remove the unnecessary stuff and reformat the code to a more common style to help you see the error:

double evaluate(TNode* p)
{
    if(outer condition 1)
    {
        if(inner condition 1)
            return;
        if(inner condition 2)
            return;
        if(inner condition 3)
            return;
        if(inner condition 4)
            return;

        // no return!
    }
    else if(outer condition 2)
        return;
    else
        return;
}

If you cannot see the error now, I recommend studying if statements until you can. This is basic knowledge that a C++ programmer must have if he wants to write bug free code.

Tom Gunn 1,164 Practically a Master Poster

Base means the longest sequence of fundamental digits before reaching 10. 10 is not limited to the decimal counting system, it is used in other bases to mean one more than the base:

Base 10, decimal: 0 1 2 3 4 5 6 7 8 9 10
Base 8, octal: 0 1 2 3 4 5 6 7 10
Base 16, hexadecimal: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10

When converting between bases, you are recounting to include new fundamental digits, or exclude missing ones. Say you want to convert hexadecimal 0x1B to decimal. Basically it goes like this:

0 = 0        A  = 10        14 = 20
1 = 1        B  = 11        15 = 21
2 = 2        C  = 12        16 = 22
3 = 3        D  = 13        17 = 23
4 = 4        E  = 14        18 = 24
5 = 5        F  = 15        19 = 25
6 = 6        10 = 16        1A = 26
7 = 7        11 = 17        1B = 27
8 = 8        12 = 18
9 = 9        13 = 19

So 1B in hexadecimal is 27 in decimal. Actually counting it out like that is probably the most naive algorithm for solving the problem, but that is the idea behind all of the more complex algorithms for base conversion. :)

Tom Gunn 1,164 Practically a Master Poster

If none of those cases are true then it goes to the else if below.

If statements do not fall through like switch cases.

#include <iostream>

int main()
{
    if (true)
    {
        std::cout << "Body of outer if\n";

        if (false)
        {
            std::cout << "Body of inner if\n";
        }
        else if (false)
        {
            std::cout << "Body of inner else if\n";
        }
    }
    else
    {
        std::cout << "Body of outer else\n";
    }
}
Tom Gunn 1,164 Practically a Master Poster
if(p->data == "+")
                        return op1 + op2;
                if(p->data == "-")
                        return op1 - op2;
                if(p->data == "*")
                        return op1 * op2;
                if(p->data == "/")
                        return op1 / op2;

If none of these cases are true, there is no default return value, and execution will fall off the end of the function without returning anything.

Tom Gunn 1,164 Practically a Master Poster

i m not getting this problem in languages like java.

Languages like Java force expressions like this to work they way the designers wanted. This is easier to manage when the compiler only has to worry about running in a virtual machine rather than any possible combination of hardware on the planet. :) The reason C++ does not enforce a strict evaluation is two fold:

  1. Leaving some expressions undefined or unspecified means compilers are free to optimize more aggressively to match the capabilities of the hardware.
  2. C++ runs on a huge number of platforms, all with different hardware and different strengths. Picking a strict evaluation may work on one machine but be very inefficient on another.

The C++ standard does not discriminate, and a lot of things are left undefined, unspecified, or implementation defined to help compilers work best for the target machine.

definitely there must b a problem wid the code of the compiler.

99% of all perceived compiler bugs are not. ;)

Tom Gunn 1,164 Practically a Master Poster

I thought that was the name of his variable.

It is. There is no magic to the name argc , it is just an idiomatic name because K&R used it. :) Whoever defines main() can choose the names of the parameters. I have seen ac and av as the next most common to argc and argv:

#include <iostream>

int main(int ac, char *av[])
{
    for (int x = 0; x < ac; ++x) std::cout << av[x] << '\n';
}
Tom Gunn 1,164 Practically a Master Poster

This code won't work because your stopping condition (argc) has not been given an initial value.

The runtime environment initializes argc before calling main(). The code will work, but it will print the arguments in order, not in reverse order.

Now all I need to know is the correct way to write a reverse for loop

The for loop does not care if you start low and go high or start high and go low. You can initialize i to argc-1, set the condition to i > 0 , and decrement i each time. That will print all of the arguments in argv except the first.

Tom Gunn 1,164 Practically a Master Poster

so shouldn't the assignment read S[i-1]='\0'?

At the end of the loop, i is indexing the right array element for placing '\0'. If you subtract 1, you will overwrite the last character. This problem is easier to see if you change the loop to stop on a new line:

for (i = 0; (c = getchar()) != '\n'; ++i)

Otherwise by putting the assignment you gave me in the body of my for loop every element of array S will be initialized to NULL?

That is why I did not put the assignment in the body of the loop. I put it after the loop, just before the call to reverse().

Tom Gunn 1,164 Practically a Master Poster

In the reverse() function, there is a test for if(*str) . That means the function is expecting str to be a string. Strings in C are sequences of characters where the last character is a sentinel with the value of 0. This value is not added automatically, you have to insert it because you are manually building a string:

S[i] = '\0';
reverse(p1);
Tom Gunn 1,164 Practically a Master Poster

The result is 100% unpredictable when you invoke undefined behavior. Trying to reason why the output is one way or another is wasted effort.

Tom Gunn 1,164 Practically a Master Poster

Your code has three immediate problems:

  1. The i variable is not initialized to 0.
  2. getchar() is only called once, not every time the loop iterates.
  3. The array is not terminated with a '\0' character.

If you fix those things, it should work.

Tom Gunn 1,164 Practically a Master Poster

The standard container classes will grow as you add to them, so there is no need to ask the user for how many inputs. You can even use a reverse iterator to go backward on most of the containers. Here is a start for research.

Tom Gunn 1,164 Practically a Master Poster

C++ treats the closing >> as the right shift operator, not two closing brackets for a template instantiation. You need to separate those two characters with white space:

Stack<Tree<int> > stack;

C++0x is the next revision of the standard, and it should fix that problem.

Tom Gunn 1,164 Practically a Master Poster

Containers are implemented using data structures, and the implementation of a container is not usually specified, so containers are a more abstract concept than data structures.

Tom Gunn 1,164 Practically a Master Poster

I do not recommend using pointer notation for indexing arrays if you do not have to. Array notation is easier to get right. Here is a sample you can use to compare with your code. Yours is very close:

#include <stdio.h>
#include <stdlib.h>

int Resize(int** list, size_t sz)
{
    int rc = 0;

    if (list)
    {
        int* tmp = realloc(*list, sz * sizeof(int));

        if (tmp)
        {
            *list = tmp;
            rc = 1;
        }
    }

    return rc;
}

int Delete(int** list, size_t* sz, size_t pos)
{
    int *data = *list;
    int x = pos;

    for (; pos < *sz-1; ++pos)
    {
        data[pos] = data[pos+1];
    }

    return Resize(list, --*sz);
}

void Populate(int* list, size_t sz);
void Display(int const* list, size_t sz);

int main()
{
    int* list = NULL;
    size_t sz = 10;

    if (Resize(&list, sz))
    {
        Populate(list, sz);
        Display(list, sz);
        Delete(&list, &sz, 3);
        Display(list, sz);
    }

    free(list);

    return 0;
}

void Populate(int* list, size_t sz)
{
    size_t x;

    for (x = 0; x < sz; ++x) list[x] = x;
}

void Display(int const* list, size_t sz)
{
    size_t x;

    for (x = 0; x < sz; ++x) printf("%-5d", list[x]);

    puts("");
}
Tom Gunn 1,164 Practically a Master Poster

This is how i call the function:

char * answer= cString('e',"Hello");

That is your problem then. :) String constants are read only. Trying to modify one through a pointer to non-const char will likely throw an access violation. If you plan to pass string constants to a function, it is best to make those pointers point to const data:

char const* cString (char letter, char const* string)

And if the function is designed to modify one of the strings passed, make sure it is not pointing to const data, and be careful to make copies of string constants first:

char * cString (char letter, char * string)
char source[] = "Hello";
char * answer= cString('e', source);
KonkaNok commented: nice solve ;) +1
Tom Gunn 1,164 Practically a Master Poster

How are you calling that function?

Tom Gunn 1,164 Practically a Master Poster

I was originally changing the address of a dynamically allocated pointer, so malloc was freaking out.

That will do it. Even if you change the value of the pointer, you must change it back to the address malloc() returned or free() will not know how to free it.

I don't want that ,I want its reference.. where it is in memory?

There are two good options for the first element:

ptrToFirstWorkOut = &ptrToProgram->week[0].workout[0];

The & operator binds to the workout, because ->, ., and [] have higher precedence. This is how you get the address of an indexed element in the array, but if you only want to first element, you can do this:

ptrToFirstWorkOut = ptrToProgram->week[0].workout;

An array name is converted to a pointer to the first element when used as a value, so you do not need to index the workout array or use the & operator.

I am trying to make my dynamicaly allocated ptrToFirstWorkOut, point to a reference of ptrToProgram->week[0].workout[0].

Without seeing your current code, I cannot say for sure, but this sounds like a memory leak. If you dynamically allocate memory, then repoint the pointer to another address, you can lose your only reference to the dynamically allocated memory.

Tom Gunn 1,164 Practically a Master Poster

the only way i know of is using the initialisation list

That is the ideal way, and it is required if the Secret class does not have a default constructor. If the Secret class does have a default constructor you can use assignment in the constructor body:

class Secret
{
private:
    int data;
public:
    Secret(int _data=0)
    {
        data = _data;
    }
};

class Mission
{
public:
    Secret mission;

    Mission()
    {
        mission = Secret(22);
    }
};
Tom Gunn 1,164 Practically a Master Poster

scanf() does not treat new line characters as different from other white space. To get line oriented input you should use something like fgets(). sscanf() is an easy way to parse the line fgets() reads:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char line[BUFSIZ];
    float dollars;

    while (fgets(line, sizeof line, stdin) &&
           sscanf(line, "%f", &dollars) != 1 ||
           dollars <= 0)
    {
        printf("invalid amount. please enter a positive amount: ");
        fflush(stdout);
    }

    printf("Received %f\n", dollars);

    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

Then terminate it there. :) If you do not do something to break the line of execution, you will step over each statement in order. Try this to kill the program from the else clause:

else
{
    system("pause");
    return 0;
}

This matches your end of main code, but I do not recommend the habit of using system() for something mundane like pausing execution. It is too risky because system() is easily turned to the dark side by replacing the pause program with something malicious. A better way to do the same thing uses the equivalent of getch():

else
{
    cout << "press any key to continue . . .";
    getch(); // not portable
    return 0;
}

And the portable way is only a bit less convenient by forcing you to type [Enter] instead of any key right away:

else
{
    cout << "press [Enter] to continue . . .";
    cin.get();
    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

Tommy... after all the good advice.. that is not what I am wanting to hear

That is how it goes sometimes. On the up side, I have never seen a rewrite worse than the code it replaced. Lessons learned before starting make for better software at the end. :)

No surrender to the evil malloc! I need that dynamic allocation!

You can still use malloc(), just roll back to before it broke and try again.

Tom Gunn 1,164 Practically a Master Poster

When you modify a variable more than once between sequence points, any result is possible. You have invoked undefined behavior.

Tom Gunn 1,164 Practically a Master Poster

I also removed the casts and i am still getting the err msg.

Removing the casts would not fix the error, but if you forgot to include stdlib.h, it would probably give you a warning too. The problem with casting malloc() in C is that it can hide that kind of error. I did not expect it to be related to your current problem though.

Can i dynamically allocate (and deallocate) memory in sub functions, or does it all have to happen in main?

You can dynamically allocate anywhere you can call a function. malloc() is nothing more than another function, after all. :)

As this is in a subfunction.. and the other uses of dynamic memory in main are not causing any issues?

I think you have issues somewhere prior to this function. It is easy to corrupt your dynamic memory even if the pointer is not related to what you corrupted. Internally, malloc() can store all kinds of bookkeeping information that can easily be overwritten with a random buffer overflow.

If the problem is beyond your current knowledge and you cannot figure it out after say a day of troubleshooting, I would advise that you cut your losses and roll back to a point where the error did not occur and start over from there. If you are building your project incrementally and saving at regular intervals, rolling back should not be a big problem because there should not be too many changes between the …

Tom Gunn 1,164 Practically a Master Poster

Try combining the tests like this:

int code;

while ((code = scanf("%f", &fDollars)) != 1 || fDollars <= 0)
{
    printf("invalid amount. please enter a positive amount: ");
    fflush(stdout);

    if (code != 1) FLUSH_STDIN();
}

Further reading for extra credit can be found here.

Tom Gunn 1,164 Practically a Master Poster

The only built in compiler I remember was for BASIC, a long time ago. I do not think even that is built into the latest Windows systems. If you want to stretch the definition of 'compiler', you can write and run HTML on a fresh Windows install. :D

The reason Linux has a built in C compiler is because of the tradition for building everything from source. Windows packages are distributed as binaries, so a compiler is not needed.

Tom Gunn 1,164 Practically a Master Poster

I thought that was the intention of the code I posted

Your code is fine, but I read nateuni's question as wanting to do something like this:

struct Program
{
    char a[SIZE];
    float b;
    char c;
    int d;
    struct Applicants e;
    struct Program* next;
};

void ClearProgram(Program* prog)
{
    // unsafe
    memset(prog, 0, sizeof *prog);
}

I thought it was important to make the distinction. :)

Tom Gunn 1,164 Practically a Master Poster
char AorB(char A, char B) { char T = rand%2 ? A : B ; return T; }

rand()%2 might not be very random. Historically rand() has been written with very non-random low order bits, and using modulus to fit the range uses the low order bits. rand()%2 only uses one bit, so you might end up with a predictable pattern like 1,0,1,01,0,1,0... A better way to pick between two options is to divide RAND_MAX by 2 and look for values in that range:

template <typename T>
T RandomChoice(T a, T b)
{
    return (rand() < RAND_MAX / 2) ? a : b;
}

p.s. I am not picking on you firstPerson. Other examples in this thread used the same thing, so my post applies to them too.

Tom Gunn 1,164 Practically a Master Poster

having const after a member function means that, that function will not
and shall not change any of its variables.

This is misleading. The method can change any of its local variables and non-const parameters, but it cannot change the state of the object. That means non-mutable data members of the class cannot be changed in a const method:

class A {
public:
    int nonmut;
    mutable int mut;

    void test(int arg) const
    {
        int local;

        local = 0; // OK
        arg = 0; // OK
        mut = 0; // OK
        nonmut = 0; // error
    }
};
Tom Gunn 1,164 Practically a Master Poster

I have been reading about memset but my understanding is it will not work for a struct.

There is nothing about a struct that causes memset() to fail, the problem is with the member types. memset(pobj, 0, n) will set n bytes starting at pobj to all bits 0. All bits 0 is not a guaranteed representation for most of the data types in C. It works for the character types and the exact width types from C99, but every other type can have trap representations from the padding bits for all bits zero that can halt a program. You described your struct as having more than the safe types, so memset() is not a safe option for the struct as a whole. The best you can do portably is manually assign values to each member and wrap it in a function for convenience.

Tom Gunn 1,164 Practically a Master Poster

Your isbal() function only tests the root, it should recursively test every node because there are trees that can be unbalanced but still have a height difference of less than 2 from the root. The definition of height balanced is that when every node is tested as an individual tree, it will be balanced according to the height rule.

Tom Gunn 1,164 Practically a Master Poster

When I stepped through on the debugger it did not come up, can anyone shed some light on what I am doing wrong?

Memory corruption can happen and not show symptoms until much later. The code you posted is not broken in any way, so the problem is probably earlier in the execution of your program. But be sure that you are including stdlib.h. Casting malloc() or calloc() can hide warnings about a missing prototype.

I think calloc allocates memory that's already aligned to the specified datatype, whereas malloc allocates memory sufficient to accomodate the specified dataype.

malloc(), calloc(), and realloc() all return a pointer aligned for assignment to any object pointer.

Tom Gunn 1,164 Practically a Master Poster

..do you mean, easy to program?

Of course, unless you do not have a computer and the only tools available are pencil and paper. Then it is easy to write but very hard to program. :D

Tom Gunn 1,164 Practically a Master Poster

I don't understand why this happen because x was assigned 0xFFFF (but when set as UINT_MAX prints 0xFFFFFFFF)

Why would that not happen? You are printing the current value of x. The first time the current value is 0xFFFF and the second time the current value is 0xFFFFFFFF. What were you expecting? That might help me to understand your question.

Why does printf("UINT_MAX = %d\n", UINT_MAX); return -1 ?

%d interprets the value as a signed int, and signed int does not go up to 4,294,967,295 when int is 32 bits. Technically you are invoking undefined behavior by overflowing a signed data type, but in practice what is happening for you is the value wraps around at the end of the range and keeps on adding until there is nothing left to add. The same thing would probably happen if you did INT_MAX + INT_MAX + 1 on a two's complement machine.

Tom Gunn 1,164 Practically a Master Poster

It should be quite obvious why. Example I have seen in working production code.

I think we might be talking about something different. I was describing the possible ways function calls in a loop condition might be interpreted by C++ if the language were designed differently. The point was that the way C++ works now is not necessarily obvious, and a beginner could be surprised with the behavior of function calls in loops if he assumed C++ worked a different, but equally viable way.

Tom Gunn 1,164 Practically a Master Poster

Sorry, Tom, but they are NOT both equally good.

Could you enumerate the reasons why you think so?

Tom Gunn 1,164 Practically a Master Poster

I do not do much Unix programming, but despite the 'Advanced' in the name, it was easy to follow when I started out. If you know the C subset of C++ well enough to follow the code I do not think there will be a problem. But you can search for recommended books and reviews here.

Tom Gunn 1,164 Practically a Master Poster

Maybe something like this?

String^ RClammer = "]";
String^ BigLine = "aaaaaaaa]aaaa";
int pos = 0;

while ((pos = BigLine->IndexOf(RClammer, pos)) != -1)
{
    BigLine = BigLine->Insert(++pos, " ");
}

Do not forget that managed strings are immutable. The Insert method does not modify the string, it returns a new one.

Tom Gunn 1,164 Practically a Master Poster

I simply didn't know that and it amazed me.

Why did it amaze you? There are two good options for how to manage function calls in the condition:

  1. Call the function every time the condition is tested.
  2. Call the function once and capture the result, then use the captured result every time the condition is tested.

Both are equally good, but I think the first follows the rule of least surprise. Then again, C++ is good at surprising everybody from day 1. ;)

Tom Gunn 1,164 Practically a Master Poster

Advanced Programming in the UNIX Environment. Anything by W. Richard Stevens is good.

Tom Gunn 1,164 Practically a Master Poster

IndexOf() returns -1 if it cannot find the value.

Tom Gunn 1,164 Practically a Master Poster

Why don't x in the former case also return a 32-bit max value

I do not understand the question. 0xFFFF is obviously not the same value as 0xFFFFFFFF, so why should they be printed as the same value? If it helps, you can mentally add leading 0's for any value that does not completely fill the space for the data type. That makes the difference easier to see:

0x0000FFFF != 0xFFFFFFFF

Tom Gunn 1,164 Practically a Master Poster

You set the capacity of vector1 in the constructor, but not the size. vector1 is still an empty list, so the first order of business is adding all of the new lists to vector1 before trying to use them. The equivalent native code for that managed declaration would be:

vector<vector<string> > vector1;

vector1.reserve(1000);
Tom Gunn 1,164 Practically a Master Poster

The generic List class is in the System::Collections::Generic namespace, not the System::Collections namespace. Either use the full name or add a using directive to the namespace:

using namespace System::Collections::Generic;
Tom Gunn 1,164 Practically a Master Poster

compileerror:
syntax error : '>'

I do not have any problem with that declaration. Can you post a complete program that throws a syntax error so that I can test it on my end?

Tom Gunn 1,164 Practically a Master Poster

The frequency of a number is how many times it appears in the list. A histogram is a visual representation of the frequency. Start by ignoring the histogram and only display the frequencies as a list of counts.

I can think of two easy ways to count the frequency. A nested loop over the numbers is one way, and storing the counts in a second array is another. Both of those are good options because there are not enough numbers to make the nested loop method too slow, and the range is not big enough to make the second array a memory hog.

Tom Gunn 1,164 Practically a Master Poster

You can pass a comparator to the set as a constructor argument, but it is just as easy to overload operator< for the struct:

#include <cstring>

typedef struct CONFIG_
{
    char app[10];
    char key[10];

    friend bool operator<(CONFIG_ const& a, CONFIG_ const& b)
    {
        return std::strcmp(a.key, b.key) < 0;
    }
} config_line;

Note that I changed _CONFIG_ to CONFIG_ . Names with a leading underscore followed by any uppercase letter are always reserved by the compiler, and names in the global namespace with a leading underscore are also reserved. _CONFIG_ is the kind of name I would expect a compiler to use for something, so it is probably dangerous to use.

Tom Gunn 1,164 Practically a Master Poster

A 2D managed list of strings with an initial capacity of 1000 would be declared like this:

List<List<String^>^>^ vector1 = gcnew List<List<String^>^>(1000);

You can use typedef to make that simpler too. ;)