Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Can anyone find the errors?

Reply
Thread Tools

Can anyone find the errors?

 
 
spacebebop@gmail.com
Guest
Posts: n/a
 
      06-27-2007
#include <cstring>
#include <iostream>
using namespace std;

class X
{
public:
X();
X( char * );
~X();
void print();

private:
char *_str;
};

class Y : public X
{
public:
Y();
Y( char * );
~Y();
void print();

private:
char *_str;
};

X::X()
{
static char *str = "X's str empty";
_str = new char[ strlen( str ) ];
strcpy(_str, str);
cout << "X(), '" << str << "'\n";
}

X::X( char *str )
{
_str = new char[ strlen( str ) ];
strcpy(str, str );
cout << "X(char *), '" << str << "'\n";
}

X::~X()
{
cout << "~X(), deallocating '" << _str << "'\n";
delete _str;
}

void X:rint()
{
cout << "X:rint():\t'" << _str << "'\n";
}

Y::Y()
{
static char *str = "Y's str empty";
_str = new char[ strlen( str ) ];
strcpy(_str, str);
cout << "Y(), '" << str << "'\n";
}

Y::Y(char *str)
{
_str = new char[ strlen( str ) ];
strcpy( _str, str );
cout << "Y(char *), '" << str << "'\n";
}

Y::~Y()
{
cout << "~Y() deallocating '" << _str << "'\n";
delete _str;
}

void Y:rint()
{
cout << "Y:rint():\t'" << _str << "'\n";
}

int main()
{
X *x[3];

x[0] = new X( "X's data-index 0" );
x[1] = new Y( "Y's data-index 1" );

// Y y( "y's data-index 2" );
// x[2] = new Y( y );

x[0]->print();
x[1]->print();
// x[2]->print();

delete x[0];
delete x[1];
// delete x[2];

return 0;
}

 
Reply With Quote
 
 
 
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      06-27-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> #include <cstring>
> #include <iostream>
> using namespace std;
>
> class X
> {
> public:
> X();
> X( char * );
> ~X();
> void print();
>
> private:
> char *_str;
> };

[...more code...]
[Subject: Can anyone find the errors?]

Which one?

I guess, the biggest error is not using std::string.

--
Thomas
http://www.netmeister.org/news/learn2quote.html
 
Reply With Quote
 
 
 
 
Ron Natalie
Guest
Posts: n/a
 
      06-27-2007
(E-Mail Removed) wrote:

Do you want to be more specific?


> #include <cstring>
> #include <iostream>
> using namespace std;


Using declarations are generally bad.

>
> class X
> {
> public:
> X();
> X( char * );
> ~X();


Classes that require destructors probably also need copy constructors
and copy assignment operators (rule of three). If you had done
anything that would have invoked copy semantics for your class
you would have had further problems.

> void print();


Did you perhaps also want to make this function virtual? Hard to tell
from your program.

>
> private:
> char *_str;
> };
>


>
> X::X()
> {
> static char *str = "X's str empty";

Deprecated conversion of const char array to char array.

> _str = new char[ strlen( str ) ];
> strcpy(_str, str);


WHOOP WHOOP... strcpy copies strlen(str) + 1 characters (the
null terminator is not counted by strlen. Undefined behavior
from writing off the end of the string.

> cout << "X(), '" << str << "'\n";


ERROR. iostream does not necessarily define ostream functions.
You need <ostream> included.

> X::X( char *str )
> {
> _str = new char[ strlen( str ) ];
> strcpy(str, str );


same bugs as before.
>
> X::~X()
> {
> cout << "~X(), deallocating '" << _str << "'\n";
> delete _str;


More undefined behavior.
Memory allocated by new[] must be freed with delete[].


Further, you'd have avoided many of these bugs if you'd
have just used std::string rather than making multiple
screw ups with char*.

 
Reply With Quote
 
Robert Bauck Hamar
Guest
Posts: n/a
 
      06-27-2007
(E-Mail Removed) wrote:

> #include <cstring>
> #include <iostream>
> using namespace std;
>
> class X
> {
> public:
> X();
> X( char * );


X(char const);

> ~X();
> void print();


void print() const;

>
> private:
> char *_str;
> };
>
> class Y : public X
> {
> public:
> Y();
> Y( char * );


Y(char const *);

> ~Y();
> void print();


void print() const;

>
> private:
> char *_str;


Hint: You already have a _str in X

> };
>
> X::X()
> {
> static char *str = "X's str empty";


static char str[] = "X's str empty";

> _str = new char[ strlen( str ) ];


_str = new char[sizeof str];

> strcpy(_str, str);


This copies strlen(str) + 1 characters! strlen() does not count the
terminating zero.

Why don't you use the std::string class?

> cout << "X(), '" << str << "'\n";
> }
>
> X::X( char *str )


X::X(char const *str)

> {
> _str = new char[ strlen( str ) ];


_str = new char[strlen(str) + 1];

> strcpy(str, str );
> cout << "X(char *), '" << str << "'\n";
> }
>
> X::~X()
> {
> cout << "~X(), deallocating '" << _str << "'\n";
> delete _str;
> }
>
> void X:rint()


void X:rint() const

> {
> cout << "X:rint():\t'" << _str << "'\n";
> }
>
> Y::Y()


X::X() is called here. If you do not want this, you could do:

: X("Y's str empty")

[snip almost equal code]
> int main()
> {
> X *x[3];
>
> x[0] = new X( "X's data-index 0" );
> x[1] = new Y( "Y's data-index 1" );
>
> // Y y( "y's data-index 2" );
> // x[2] = new Y( y );
>
> x[0]->print();
> x[1]->print();


This shall print "X:rint()\tX's str empty\n"

http://www.parashift.com/c++-faq-lit...functions.html

> // x[2]->print();
>
> delete x[0];
> delete x[1];


This line is undefined behaviour:

http://www.parashift.com/c++-faq-lit....html#faq-20.7

> // delete x[2];
>
> return 0;
> }


--
rbh
 
Reply With Quote
 
Alan Johnson
Guest
Posts: n/a
 
      06-27-2007
Ron Natalie wrote:
> (E-Mail Removed) wrote:
>> cout << "X(), '" << str << "'\n";

>
> ERROR. iostream does not necessarily define ostream functions.
> You need <ostream> included.


By this do you mean to imply that a minimal Hello world program using
the C++ IO library would require both <iostream> and <ostream>? That is:

#include <iostream>
#include <ostream>
int main()
{
std::cout << "Hello, world!\n";
}

My reading of the standard agrees with that interpretation. <iostream>
is needed to declare std::cout, but it is declared as extern, which
thanks to 7.1.1.8 means that class std:stream need not be defined at
that point. Thus we must include <ostream> if we want to use operator<<
of class std:stream.

This is somewhat surprising to me since there are literally thousands of
examples where only <iostream> is included to allow someone to use
std::cout. Even Stroustrup has such an example:
http://www.research.att.com/~bs/hello_world.c

--
Alan Johnson
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      06-27-2007
On Jun 28, 10:01 am, Ron Natalie <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > _str = new char[ strlen( str ) ];
> > strcpy(_str, str);

>
> WHOOP WHOOP... strcpy copies strlen(str) + 1 characters (the
> null terminator is not counted by strlen. Undefined behavior
> from writing off the end of the string.
>
> > X::X( char *str )
> > {
> > _str = new char[ strlen( str ) ];
> > strcpy(str, str );

>
> same bugs as before.


Actually it is different bugs. The second one
does not overflow _str because it never writes
to it. The undefined behaviour does not come
until this constructor is called with a string
literal as the argument:

>> x[0] = new X( "X's data-index 0" );


which I think is the first occurrence of UB
at runtime.

 
Reply With Quote
 
BobR
Guest
Posts: n/a
 
      06-28-2007

Alan Johnson <(E-Mail Removed)> wrote in message...
> Ron Natalie wrote:
> > (E-Mail Removed) wrote:
> >> cout << "X(), '" << str << "'\n";

> >
> > ERROR. iostream does not necessarily define ostream functions.
> > You need <ostream> included.

>
> By this do you mean to imply that a minimal Hello world program using
> the C++ IO library would require both <iostream> and <ostream>? That is:
>
> #include <iostream>
> #include <ostream>
> int main(){
> std::cout << "Hello, world!\n";
> }


That is a "more correct" way of doing it.

>
> My reading of the standard agrees with that interpretation. <iostream>
> is needed to declare std::cout, but it is declared as extern, which
> thanks to 7.1.1.8 means that class std:stream need not be defined at
> that point. Thus we must include <ostream> if we want to use operator<<
> of class std:stream.
>
> This is somewhat surprising to me since there are literally thousands of
> examples where only <iostream> is included to allow someone to use
> std::cout.


99 out of 100 compiler implementations have both <istream> and <ostream>
included in <iostream> (, but not 'required').
It's that 1 that the wording in the standard goes out of it's way to not
exclude.
<G>

The <ostream> thing has been run-around-the-barn many times in this NG
alone.

--
Bob R
POVrookie


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-28-2007
On Jun 28, 1:23 am, Alan Johnson <(E-Mail Removed)> wrote:
> Ron Natalie wrote:
> > (E-Mail Removed) wrote:
> >> cout << "X(), '" << str << "'\n";


> > ERROR. iostream does not necessarily define ostream functions.
> > You need <ostream> included.


> By this do you mean to imply that a minimal Hello world program using
> the C++ IO library would require both <iostream> and <ostream>? That is:


> #include <iostream>
> #include <ostream>
> int main()
> {
> std::cout << "Hello, world!\n";
> }


That's what the standard says.

> My reading of the standard agrees with that interpretation. <iostream>
> is needed to declare std::cout, but it is declared as extern, which
> thanks to 7.1.1.8 means that class std:stream need not be defined at
> that point. Thus we must include <ostream> if we want to use operator<<
> of class std:stream.


In fact, the way I understood the intent was that <iostream>
really should just include <iosfwd> and the extern declarations.
The whole point of breaking the thing down into multiple headers
was that you don't pull in tons of lines that you don't need
each time. For whatever reasons, however, all (or at least all
I'm aware of) implementations do include <istream> and <ostream>
when you include <iostream>. So at the last reunion, the
committee voted to bring the standard in line with existing
implementations and most peoples expectations. Unless a future
vote rescends this decision, the #include <ostream> will not be
necessary in the next version of the standard.

> This is somewhat surprising to me since there are literally
> thousands of examples where only <iostream> is included to
> allow someone to use std::cout. Even Stroustrup has such an
> example:http://www.research.att.com/~bs/hello_world.c


I know. And those examples have conditionned user expectations,
and user expectations have conditioned implementations.
Personally, I would have prefered the reverse, that the
implementation only included the minimum, but it's too late now.
Although I'm not sure it's a good general principle, in this
case, I think it's best to align the standard with existing
practice.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
bjarne
Guest
Posts: n/a
 
      06-28-2007
On Jun 28, 6:42 am, James Kanze <(E-Mail Removed)> wrote:
>
> In fact, the way I understood the intent was that <iostream>
> really should just include <iosfwd> and the extern declarations.
> The whole point of breaking the thing down into multiple headers
> was that you don't pull in tons of lines that you don't need
> each time. For whatever reasons, however, all (or at least all
> I'm aware of) implementations do include <istream> and <ostream>
> when you include <iostream>. So at the last reunion, the
> committee voted to bring the standard in line with existing
> implementations and most peoples expectations. Unless a future
> vote rescends this decision, the #include <ostream> will not be
> necessary in the next version of the standard.
>
> > This is somewhat surprising to me since there are literally
> > thousands of examples where only <iostream> is included to
> > allow someone to use std::cout. EvenStroustruphas such an
> > example:http://www.research.att.com/~bs/hello_world.c

>
> I know. And those examples have conditionned user expectations,
> and user expectations have conditioned implementations.
> Personally, I would have prefered the reverse, that the
> implementation only included the minimum, but it's too late now.
> Although I'm not sure it's a good general principle, in this
> case, I think it's best to align the standard with existing
> practice.
>


There is one more piece to this puzzle. At the time where the
standards text for <iostream> was written, essentially all code was
written using <iostream> and worked. The standard (unintentionally, as
far as I'm concerned, and surprisingly) broke that code. By making
code using just <iostream> legal, the standard was simply brought
*back* into line with reality.

-- Bjarne Stroustrup; http://www.research.att.com/~bs

 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      06-28-2007
Ron Natalie <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
>
> Do you want to be more specific?
>
>
>> #include <cstring>
>> #include <iostream>
>> using namespace std;

>
> Using declarations are generally bad.


Actually, this is a using *directive*. A using declaration would be
something like:

using std::cout;

Personally, I use using declarations in my .cpp files, but this is
largely personal preference so I will not expect to get into this
debate.

Obviously, using directives (and declarations as well) in headers are
bad, which is what I think you were trying to hint at.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to exclude action of Find::Find::find in subdirectories withknown names? vdvorkin Perl Misc 3 02-14-2011 05:28 AM
How to exclude action of Find::Find::find in subdirectories withknown names? vdvorkin Perl Misc 0 02-10-2011 05:18 PM
Does anyone Know Anyone at Maas Rowe I can talk to channing28270@gmail.com Computer Support 3 07-05-2006 08:27 AM
can find ImageButton but can't find button ad ASP .Net 2 11-20-2005 11:35 AM
Find.find does not find orphaned links? Wybo Dekker Ruby 1 11-15-2005 02:50 PM



Advertisments