Tom Gunn 1,164 Practically a Master Poster

Even the delete operator is executed, the last two output statements are working same the first two output statements..

How is this possible...?????????????????

When you free memory, it may or may not be reused immediately for something else. If it is not reused, you can still access the pointer and get what was there before. But it is not safe to rely on that behavior because there is no way to tell if the memory was reused. The only way to guarantee that you own the memory is not to free it until you are really done with it.

Technically your code invokes undefined behavior because you use a pointer to access memory after it was freed. Undefined behavior is very bad because it makes your program totally unpredictable.

Tom Gunn 1,164 Practically a Master Poster

If all of the fields have an overloaded copy constructor or assignment operator, or if they are built in types, you can just do assignments of all fields and everything should work right:

// use copy constructors and initialization
CMatrix::CMatrix(const CMatrix& m)
    : _s_row(m._s_row),
      _s_col(m._s_col),
      base_mat(m.base_mat)
{
    // all work in initializer list
}
// use assignment
CMatrix::CMatrix(const CMatrix& m)
{
    _s_row = m._s_row;
    _s_col = m._s_col;
    base_mat = m.base_mat;
}

The first is recommended because it tends to be more efficient to initialize to what you want instead of default initializing and then assigning what you want.

nanchuangyeyu commented: quite explicit guide +1
Tom Gunn 1,164 Practically a Master Poster

It would be so much better to rely on the standard headers than your memory leaking program.

Technically it leaks memory, but realistically, it is probably not going to be run on an OS that does not free memory when a process ends. As an example of how to allocate memory for a 2D array using new[], the code is fine.

It could be better, of course. :) As an example of both allocating and freeing, the code is more complete and even the technical memory leak is plugged. Good examples of heap memory should free as well as allocate. Here is the better code using the same style as monkey_king:

#include <iostream>


int **allocs(int x,int y){
    int **ret  = new int*[x];
    for(int i=0;i<x;i++)
        ret[i] = new int[y];
    return ret;

}


void deallocs(int **array, int x){
    for(int i=0;i<x;i++)
        delete[] array[i];
    delete[] array;

}


int main(){
    int **array = allocs(4,5);
    int p = 0;

    for(int i=0;i<4;i++)
        for(int j=0;j<5;j++)
            array[i][j] = p++;

    // check the array
    for(int i=0;i<4;i++){
        for(int j=0;j<5;j++)
            std::cout << array[i][j] << ' ';
        std::cout << '\n';
    }

    deallocs(array, 4);

}

I think direct heap allocation should be a last resort. There are so many safer and easier ways than allocating memory yourself, and it takes too much brainpower to make sure that you are not introducing any bugs with your memory handling. A big source of bugs comes from manually handling your memory. That is why the newer languages have garbage collection.

you may want to …

Tom Gunn 1,164 Practically a Master Poster

A little addition on:

Array names become pointers

Yes, an array name is a constant pointer to the first element of that array.

An array name is the name of an array object, nothing more, nothing less. When used as a value, it is converted to a pointer to the first element. When used as an object, there is no conversion. It's a subtle difference, but important when you get to object usage like char a[] = "string" , &a , and sizeof(a) . All of those work the right way because the array is not converted to a pointer.

tux4life commented: Yes you're right :) +15
Tom Gunn 1,164 Practically a Master Poster

yes, you're right.

even though it works for this trivial example, not casting it properly is a bad habit to get into.

the correct way to initialize it is:

char q[16];
char *p = [b](char *)[/b]&q;
strcpy(q,"abc");

So you get the wrong type, then cast it to the right type and rely on the starting address being the same for both to make it all work out. Why not use the right type from the start and not need to cast at all?

/* better */
char q[16];
char *p = q;
strcpy(q,"abc");

Array names become pointers when used as a value. But you don't need to do any of that because q can be passed to strcpy directly, or even initialized to a string constant:

/* easier */
char q[16];
strcpy(q, "abc");
/* even easier */
char q[16] = "abc";

I can't figure out why you have a magic number of 16, but there's probably a reason. Otherwise you don't need any size if you initialize to a string constant:

/* easiest */
char q[] = "abc";

You can't get much shorter than that for a modifiable string. ;)

Salem commented: Quite so +36
tuse commented: super cool post +2
Tom Gunn 1,164 Practically a Master Poster

The read() function returns the stream, so you should be able to signal EOF to stop the first loop. On Linux it's a Ctrl+D key combination and on Windows it's Ctrl+Z.

theashman88 commented: Quick help +1
Tom Gunn 1,164 Practically a Master Poster

You can declare a function without defining it if you replace the curly brackets and code with a semicolon:

void Menu();

void McDonalds()
{
    // ...
}

void Menu()
{
    // ...
}
rtwister commented: thanks +1
Tom Gunn 1,164 Practically a Master Poster

if i compare number of his posts or reputation points or solved threads, i think Ramy or Scott(sknake) must be granted these before than him.

If the criteria for being featured are post count, solved thread count, and reputation points then there are a lot of people in line before essential, or the two you mentioned. There has to be some other criteria, because look at people like Salem who aren't featured but blow everyone else away.

I dont know but this is not fair, and this will demotivate our valuable posters

I think the valuable posters are more interested in being valuable than being recognized as valuable.

ddanbe commented: Nice:I think the valuable posters are more interested in being valuable than being recognized as valuable. +7
Tom Gunn 1,164 Practically a Master Poster

*Implementation of the Traveling Salesman Algorithm on Networking Systems.
*Graph Traversal System Using Best Path Method .
*Analysis on the Different Advanced Algorithms
*Implementation of the Closest Pair Algorithm on Networking Systems
*Comparative Study on the Efficiency of Sorting Algorithms

These have been done to death. If you are lazy you can search for stuff other people have done, but if you want a thesis that stands out among the crowd, coming up with something more unique is recommended. ;)

*Comparative Study on the Structure of Java and C Sharp Languages

Yawn. How about something challenging and useful like a comparative study on the structure of C# and Haskell throughout their evolution, with an eye toward the benefits of functional programming over imperative programming and vice versa?

Salem commented: Yeah, I thought "thesis" was supposed to be a unique effort, not some rehash +36
Tom Gunn 1,164 Practically a Master Poster

All strtok does is replace the delimiter with '\0'. If you skip over it, you'll find the rest of the string:

#include <stdio.h>
#include <string.h>

int main()
{
    char s[] = "a|b|c|d|e|f|g";
    char *tok = strtok(s, "|");

    printf("%s\n%s\n", tok, tok + strlen(tok) + 1);

    return 0;
}

The only problem is there is no way to tell if strtok is finished until it returns NULL, and by then it's too late. If you know that there is more than one token, this works, but if not, you have to use something other than strtok to get the first token or do some extra testing:

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

int main()
{
    char s[1024];
    char *p;

    printf("Type a sentence: ");
    fflush(stdout);

    if (!fgets(s, 1024, stdin)) return EXIT_FAILURE;
    if (p = strchr(s, '\n')) *p = '\0';

    if (!strpbrk(s, " \t\r\v")) printf("%s\n", s);
    else
    {
        char *tok = strtok(s, " \t\r\v");

        printf("%s\n%s\n", tok, tok + strlen(tok) + 1);
    }

    return 0;
}
tux4life commented: The most useful post in this thread :) +12
Tom Gunn 1,164 Practically a Master Poster

On gcc compiler, 2nd and third printf() call taking value of i and j automatically..
but if in first printf() call ,i don't give i and j as argument then that prints garbage value..
can nyone explain it plz..

It happens to work out that way with how printf and varargs work on gcc. varargs probably look down the call stack unconditionally, and the call stack probably doesn't physically change until values are overwritten. The second call does not overwrite the two values and they stay the same for the sequential calls.

It's really pointless to explain how undefined behavior works because it could be different the next time you run the program, or in the next revision of the compiler, and certainly on a different compiler. Just don't do it. ;)

Like tux4life said, you need at least as many values as there are format specifiers in the format string. If there are fewer values than format specifiers, it's undefined behavior. There can be more values, and the extra values will be ignored without it being UB, but that will confuse people reading your code.

tux4life commented: You clarified my doubt :) +12
Tom Gunn 1,164 Practically a Master Poster

Is there a 'z' involved, as in the total number of groups?

z can be calculated using x and y, but having an actual z makes it harder to handle an x that isn't perfectly divisible by y.

jephthah commented: Bork Bork Bork +12
Tom Gunn 1,164 Practically a Master Poster

Except for deleting line 15, what Ancient Dragon wants you to do will make your code more portable. That's a good goal, but you have a real problem to fix first: integer overflow. p, r and t can't be very big before multiplying them together will overflow an int, and overflowing an int is a lot worse than all of the other stuff Ancient Dragon is worrying about.

You can work around integer overflow by not allowing it, and that means testing for overflow before it happens. Here is your code with one of those tests added:

#include <iostream>
#include <stdexcept>
#include <climits>

using namespace std;

namespace Daniweb
{
    int Product(int a, int b, int max=INT_MAX)
    {
        if (b > max / a) throw range_error("integer overflow");
        
        return a * b;
    }

    float si(int p, int r, int t, int max=INT_MAX)
    {
        return Product(Product(p, r, max), t, max) / 100.f;
    }
}

int main() 
try
{
    int p = 1000, 
        r = 1000, 
        t = 1000;

    cout << "max test = ";
    cout << fixed << Daniweb::si(p, r, t) << '\n';
    cout << "\t!passed!\nlimit test = ";
    cout << fixed << Daniweb::si(p, r, t, 1000000000) << '\n';
    cout << "\t!passed!\noverflow test = ";
    cout << fixed << Daniweb::si(p, r, t, 999999999) << '\n';
    cout << "\t!passed!\n";
}
catch (range_error& e)
{
    cerr << e.what() << '\n';
}
Ancient Dragon commented: Good point :) +36
Tom Gunn 1,164 Practically a Master Poster

Assembly::GetExecutingAssembly()->Location; will give you the full path of the running program. The 'file date' isn't specific enough. Do you want the creation time, the last read, last write? But the File class has that stuff:

String^ path = Assembly::GetExecutingAssembly()->Location;
DateTime^ fileDate = File::GetCreationTime(path);
Tom Gunn 1,164 Practically a Master Poster
return *output;

That line is really the whole problem. *output is not a pointer to char, it's a char. You're also trying to return a pointer to a local array. When the function returns, the local array goes bye bye and you can't use a pointer to it anymore.

Try passing the temporary array in as a parameter and return it at the end. That way you don't have to worry about it going out of scope:

char *extract(char output[11], int *pos, char *array) {
    int max = *pos + 10, 
        count = 0;

    while (*pos != max) {
        output[count] = array[*pos];
        count++;
        (*pos)++;
    }

    return output;
}

int pos = 0;
char *string = "BlahBlahBlahBlahBlahBlah......";
char output[11] = {0};

puts(extract(output, &pos, string));
puts(extract(output, &pos, string));
Hiroshe commented: Lots of help. Thanks +2
Tom Gunn 1,164 Practically a Master Poster

jephthah's way is the safest and most portable once you fix the nonportable assumptions:

#include <stdio.h>

#if __STDC_VERSION == 199901L
#include <stdint.h>
#else
/* change to fit the compiler */
typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
#endif

#define IPV4

#if defined(IPV4)
#define NBYTES 4
#elif defined(IPV6)
#error IPV6 not supported
#else
#error No valid IP version protocol defined
#endif

int main()
{
    uint32_t ipAddress = 167840383;
    uint8_t  octet[NBYTES];
    int x;

    for (x = 0; x < NBYTES; x++)
    {
        octet[x] = (ipAddress >> (x * 8)) & (uint8_t)-1;
    }

    for (x = NBYTES - 1; x >= 0; --x)
    {
        printf("%d", octet[x]);

        if (x > 0) printf(".");
    }

    printf("\n");

    return 0;
}

The biggest assumption jephthah's code makes is that unsigned int is 4 bytes and a byte is 8 bits. If they are, the math works out, but if they are not, bad things can happen.

I fixed those two assumptions by using the explicit sized types from C99's <stdint.h>, and for everyone playing at home without a C99 compiler, I defined uint32_t and uint8_t as an example only. Don't come crying to me if unsigned char isn't 8 bits on your computer. ;)

There is another way that's easier to get right. Instead of playing with bit operators, make a union with two members. The first member is a 32 bit type and the second is an array of 4 8 bit types. They take the same memory so when you assign the …

jephthah commented: a bit overly pedantic ... but solid +12
csurfer commented: Great code there... +3
Tom Gunn 1,164 Practically a Master Poster

Have you read Beej's guide?

Tom Gunn 1,164 Practically a Master Poster

http://siddhant3s.googlepages.com/how_to_tell_rusted_cpp.html#SECTION00044000000000000000

That link is really opinionated. using namespace std; says that every name in the std namespace is available without having to prefix it with std:: . using std::{name}; says that only the specified name is available without a prefix. Without either of those, you have to prefix every instance of every name in the namespace with std:: .

There's no 'correct' usage. The most flexible choice is prefixing everything with std:: . That way you cherry pick which names to use and there's no chance of clashes. But it's very verbose and lines get long really fast.

For a few names used a lot, using std::{name}; is a good way to tame the verbosity of the prefix method. You know what names are prefixed and this can be put in the global scope without worrying about it:

#include <iostream>
#include <vector>

using std::cout;
using std::vector;

int main()
{
    vector<int> v;
    int input;

    cout << "Type some numbers: ";

    while (std::cin >> input) v.push_back(input);

    vector<int>::const_iterator x = v.begin();
    vector<int>::const_iterator y = v.end();

    while (x != y) cout << *x++ << '\n';
}

A better practice is putting the using std::{name}; at the top of the block you use it in. That way you still get the verbosity savings and also make accidental clashes easier to find and fix. Anything in the global scope still gets a prefix:

#include <iostream>
#include <vector>

template <class Container>
void PrintContainer(Container container)
{
    using std::cout;

    Container::const_iterator x = container.begin(); …
Nick Evan commented: Solid advice IMO +19
Ancient Dragon commented: great explanation :) +36
tux4life commented: Excellent! +10
siddhant3s commented: Well explained +14
StuXYZ commented: Good post +5
Azurea commented: Awesome explanation! Thanks! +2
Tom Gunn 1,164 Practically a Master Poster

you need memset() to set a default value.

memset() is not needed. You can do it without calling a function by using an initializer for the array:

int array[4][2] = {0}; /* init all elements to 0 */
Hiroshe commented: thanks +2
Tom Gunn 1,164 Practically a Master Poster

There is no point in understanding the output. It's undefined behavior. The output could be different the next time you run the program. UB also makes the rest of the program undefined so you have to understand all of that craziness too. It's a waste of resources to understand UB, just don't invoke it with stuff like this. ;)

jephthah commented: yep. +12
Tom Gunn 1,164 Practically a Master Poster

Next time, try to elaborate your point so that the other person can comment on it.

Well, now you know how it feels to get negative rep you don't agree with. No chance to defend, just BAM, hit and run.

Linux is really a good designed OS.

Linux is a good OS. I agree.

I don't really want to start a flame war, but this is the truth.

Right. If you didn't want to start a flame war, you wouldn't have made such an inflammatory post. Sorry, but I refuse to take the bait.

iamthwee commented: amen +21
Tom Gunn 1,164 Practically a Master Poster

Good luck and thanks!

I think it would be better to show your code with the pointer stuff so that someone can help you understand where you went wrong than to show your code without the pointer stuff and hope somebody does all of your work for you.

Salem commented: Indeed +36
Tom Gunn 1,164 Practically a Master Poster

You don't always have to store the actual value the way float and double do. If the problem allows it, you can write your own data type that uses exponent representation just like you showed in your post:

typedef struct 
{
    long base;
    long exponent;
} exponent_t;

Then do math on it like you learned in grade school. :)

kvprajapati commented: Good advice. +3
Tom Gunn 1,164 Practically a Master Poster

It helps to know what you expected. I'll guess that you wanted -25.0. Here's why you get -100.0. a=2*(s-u*t)/squ(t); uses the squ macro, and squ replaces itself with the macro text x*x with x replaced by the argument t. Your statement looks like this after the replacement:

a=2*(s-u*t)/t*t;

* and / have the same precedence and are evaluated left to right. If you wanted -25.0 as a result, x*x has to be surrounded by parentheses:

a=2*(s-u*t)/(t*t);

That's why it's a good habit to surround your macro text expressions with parentheses. And for the same reason, the macro parameter:

#define squ(x) ((x)*(x))

You should be very careful with macros like this because if you pass an expression with side effects as the argument, the side effect will be evaluated twice:

int b = 1;

printf("%d\n", squ(b++)); /* squ(b++) replaced with ((b++)*(b++)) */
printf(“result :%f”,a);

If you don't print a '\n' character somewhere, the output might look weird.

jephthah commented: nice explanation +11
tux4life commented: I agree with you :) +10
Tom Gunn 1,164 Practically a Master Poster

Wrong. Wrong. Wrong.

Structures, or any other variable, are not initialized to zero or any other value "by default" ... just because your compiler happens to do so, does not mean someone else's compiler does.

this error is probably the single-most source of broken code, and endless debugging efforts.

thanks for propagating crappy coding practice. :icon_rolleyes:


.

I'm sorry, but you are the one who is wrong. Since we're talking about a C99 feature, I'll quote the C99 standard concerning initializer lists:

If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.

If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.

If there's no initializer list, you're right about local variables. …

Tom Gunn 1,164 Practically a Master Poster

If you just want a reference, "C: A Reference Manual" is the best. A good beginner book is "C Primer Plus".

jephthah commented: C: A Reference Manual is extremely well reviewed. i'll have to check that out +11