• Dangerous things in C++

    From Nightfox to All on Sat May 21 08:46:45 2011
    There are some interesing ways that C++ lets you do unsafe things.. For example, consider the following code snippet:

    goto DONE;

    int *anInt = new int;

    DONE:
    delete anInt;

    That code will compile without any warnings (at least with Visual Studio 2010), but when you run it, the program will crash. I just recently realized you could skip around variable declarations like this and go to a place where it will try to clean up variables that haven't even been declared. This is one reason why I think it's good to avoid using the 'goto' statement.

    Here's some more unsafe playing with pointers:
    int *intPtr = new int;
    *intPtr = 20;
    int& intRef(*intPtr);
    delete intPtr;

    intRef is a reference to an int, but it now contains garbage, since the memory used by intPtr was freed. Later in the code, if you weren't aware of this fact, it could be hard to track down the issue.

    For that matter, you could also do this:
    int& intRef(*(int*)NULL);

    Basically, that is making a reference to an int using a NULL pointer. This compiles without any errors or warnings, but intRef will not have anything valid, and the program will probably crash if you run it.

    Then there's also interpreting one type of pointer as another type:
    int anInt = 0;
    std::string *aString = (string*)&anInt;

    This compiles without any errors, but the program will crash if you try to do string stuff with aString because it doesn't actually point to a string. Interestingly, the static_cast operator to do the same cast will result in a compile error:
    int anInt = 0;
    string *aString = static_cast<string*>(&anInt);

    The compiler error will tell you that static_cast cannot convert from int* to std::string*. At least the static_cast operator provides some protection - probably the reason it was added. However, this is easily circumvented if you cast the int pointer to a void pointer:
    string *aString = static_cast<string*>((void*)&anInt);

    So, it seems that there is a way to get around the protections that C++ gives you. C++ gives you a lot of rope to hang yourself with - perhaps even more than C, since C++ is compatible with C and also adds all of its own stuff.

    Nightfox
  • From Nightfox to Deavmi on Fri Aug 4 12:41:31 2017
    Re: Re: Dangerous things in C
    By: Deavmi to Nightfox on Fri Aug 04 2017 06:33 pm

    `new int` allocates memory for holding data of type `integer` and thereturns a pointer to it which you assigned to a variable of type `int pointer`.

    `delete anInt` would look at the pointer in `anInt` and then ask the kernel to de-allocate memory at that address.

    Am I right?

    Yes, that's correct.

    Nightfox