Hottest Forum Q&A on CodeGuru - December 1st

Introduction:

Lots of hot topics are covered in the Discussion Forums on CodeGuru. If you missed the forums this week, you missed some interesting ways to solve a problem. Some of the hot topics this week include:


Can I catch an Exception if I call delete on a dangling pointer? (top)

Thread:

Ram_Gupta does have some problems in his simple code where he got a runtime Exception. He knows that he is using an unlocated pointer, but wants to know if he can catch such an exception.

When I try to run the code below, it gives a runtime exception
although I am ctching the exception. Plz suggest something.
I can't check the pointer against NULL.
#include <iostream>
#include <stdexcept>
using namespace std;
void main()
{
    char* p;
    try
    {
        delete p;
    }
    catch(exception ex)
    {
      cout<<"hello"<<endl;
    }
}
The problem is Ram_Gupta is not able to change the original code.
In the originalm one class is having some pointer data member. In
the destructor he is freeing the memory but doesn't assign the
pointer to NULL. So somehow he has assigned the object to someone
else, so that pointer has become a dangling one. I don't want to
change his overloaded = oparetor nor do i wanna provide a copy
ctor. So i wanna call delete, catch the exception and cooly
come out without any runtime error.

Graham explained the solution very well. You should always try to fix the probem. Don't try to patch it over. Here is exactly his oppinion about this and I agree fully with him.

To reiterate:

It is undefined behaviour.

This means that, just because this particular compiler (or version of the compiler) throws an exception, you can't rely on that. The next upgrade to your compiler may do something different. For example, it may just call exit() immediately. It might reboot your machine or reformat the hard disk. it could do anything; that's what undefined behaviour means.

Fix the problem; don't try to patch it over. Your desire not to provide a copy ctor is unreasonable. Do a deep copy, not a shallow one; implement a reference counted smart pointer if you don't want a deep copy, but do something positive to address the problem, rather than rely on behaviour that is intrinsically unreliable.

If you still want to catch the exception, you can use SException under Windows.


How do I use sprintf with std::string? (top)

Thread:

avi123, a regular visitor of CodeGuru, is wondering whether he can use sprintf with std::string instead of a char*.

I was wondering how do I do this using std::string instead of char*.
sprintf(szStr, "%.2f", dNum);

std::string does not support such a function. Instead, use std::stringstream.

Somebody might think that std::string.c_str() returns a char*, so there shouldn't be any problem when using it in sprintf. But, that's wrong.

std::string::c_str() returns a const char*, so you can't pass it to sprintf.


How should I pass the std::string as a function parameter? (top)

Thread:

This question is asked again by avi123. He has several functions that accept std::string as a parameter. Now, he wants to know whether he should send it via reference or via value. What is your oppinion about that?

I have planty of functions which have std::string as parameter the
string value isn't change inside those functions (I send them as a
const). My question is, should I pass the std::string by value
like it was int/double etc or by reference like I do with structs?

I mean something like this:
const std::string myString
func1(myString)
should I define func1 like this:
std::string func1(const std::string& myStr)
or
std::string func1(const std::string myStr)
Is std::string is a big structure needs using reference?

Andreas Masur, a super moderator of CodeGuru, explained the answer very well. If a function does not change the contents of a variable, you should basically pass it as a constant reference. However, this is only a matter while dealing with structures and/or classes. Simple data types can be still passed by value because passing by reference would only add unnecessary overhead.

In addition, you might want to take a look at this article.


How do I push_back a vector? (top)

Thread:

halmark6Z is working on a code in which he needs to push_back an object into a vector.

I`ve puzzled the next one rather long, and I4m pretty stuck with it:
void loadAnimals(const vector<Animal*> *animals,
                 const char* filename)
{
  ...
  ...
  // open file, etc.
  ...
  Animal *animal = NULL;
  // bunch of code to read animal data from the file.
  // the animal's type (inheritance) is determined here
  // this part works fine.
  // for example,     animal = new Dog();

  // puzzled about this
  animals->push_back(*animal);       // won't compile
  // animals->push_back(&animal);    // won't compile
}
how do I push the object into the vector ?

Can you see the error?

& is the address of operator, which will give you Animal**. * as the dereference operator, which will give you Animal.

Because you already have Animal*, you merely need to do this:

animals->push_back(animal);

Besides that, you can also take a look at this article. I suggest you also take a look at the thread, because Philip Nicoletti explains the answer very well, with some small examples.


What does the C++ standard say? (top)

Thread:

KevinHall is trying some code that compiles on one compiler and fails on another. But why?

What does the C++ standard say with regards to the following
piece of code? I am attempting to compile someone else's code on
two different compilers, and on one it fails. The code is
something like this:
const int iMax = 50;

void SomeFunction()
{
    for(int i=0; i<iMax; ++i)
        doSomething(i);

    for(int i=0; i<iMax; ++i)
        doSomethingElse(i);
}
The reason one fails is it says that i is defined twice (in both
for statements). So the question I have is does defining a
variable within a for loop limit the scope of the variable to the
for loop? Or does it effectively define the variable in the scope
before the loop? Which compiler is more compliant to the standard
in this particular area?

[Source=MSDN]

The C++ standard says that a variable declared in a for loop shall go out of scope after the for loop ends. For example:

for (int i = 0 ; i < 5 ; i++) {
   // do something
}
// i is now out of scope under /Za or /Zc:forScope

By default, under /Ze, a variable declared in a for loop remains in scope until the for loop's enclosing scope ends. /Zc:forScope enables standard behavior of variables declared in for loops without needing to specify /Za. It is also possible to use the scoping differences of the for loop to redeclare variables under /Ze as follows:

int main()
{
   int i = 0;   // hidden by var with same name declared in for loop
   for ( int i = 0 ; i < 3; i++ )
   {
   }

   for ( int i = 0 ; i < 3; i++ )
   {
   }
}

This more closely mimics the standard behavior of a variable declared in a for loop, which requires variables declared in a for loop to go out of scope after the loop is done. When a variable is declared in a for loop, the compiler internally promotes it to a local variable in the for loop's enclosing scope even if there is already a local variable with the same name.

Paragraph and verse:

The Standard, 6.5.3 / 3:
If the forinitstatement
is a declaration, the scope of the name(s) declared extends to
the end of the forstatement.
[Example:
int i = 42;
int a[10];
for (int i = 0; i < 10; i++)
a[i ] = i;
int j = i; // j = 42
.end example]



About the Author

Sonu Kapoor

Sonu Kapoor is an ASP.NET MVP and MCAD. He is the owner of the popular .net website http://dotnetslackers.com. DotNetSlackers publishs the latest .net news and articles - it contains forums and blogs as well. His blog can be seen at: http://dotnetslackers.com/community/blogs/sonukapoor/

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds