From: Daniel Krügler on
On 16 Apr., 23:43, mpho <tjab...(a)gmail.com> wrote:
> This seems straightforward but gives this runtime error: terminate
> called after throwing an instance of 'std::bad_alloc' , what() :
> std9bad_alloc . I have:
>
> class X {
> int sz;
> T *ptr;
>
> public:
> X(int s, T *p) : sz(s), ptr(new T[s])

Note that you are invoking the array form of new here,
new[].

> {
> assert(ptr != NULL);
> for (int i = 0, i < sz; i++)
> ptr[i] = p[i];
> }
>
> //other members
>
> ~X() { delete ptr; ptr = NULL; }

.... And here you are using the scalar form of delete - undefined
behaviour,
see [expr.delete]/2. To fix this, use

delete[] ptr;

instead (The final nullification of ptr in the d'tor is essentially
superfluous).

> };
>
> class Y {
> X xobj
>
> public:
> Y(int s, T *p) : xobj(s, p) { } //OK?
> //other members
> ~Y() { } //OK?
> };
>
> then
>
> int main(){
>
> ar[10] = {ten values};
> Y yobj(10, ar); //problem here(?)
> ......
> .....
>
> }
>
> What's the problem above?
> Thank you.

There are several syntactic issues and missing code, but
the new[]/delete mismatch is probably your main problem.

Basic rule 1: Always combine new/delete and new[]/delete[].

Basic rule 2: If possible, replace "manual" resource allocations
and use a full-fledged class for doing this - this is the basic idiom
of RAII (Resource Acquisition Is Initialization). Your example code
above is the classical use-case for std::vector<T> and there
is little excuse for not using it here.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gerhard Menzl on
mpho wrote:

> This seems straightforward but gives this runtime error: terminate
> called after throwing an instance of 'std::bad_alloc' , what() :
> std9bad_alloc . I have:
>
> class X {
> int sz;
> T *ptr;

Unknown type T.

>
> public:
> X(int s, T *p) : sz(s), ptr(new T[s])
> {
> assert(ptr != NULL);

What's the purpose of the assert here? Do you want to make sure the
standard allocator is working correctly? Unless you have overloaded
new[] and implemented it incorrectly, ptr cannot ever be null here.

> for (int i = 0, i < sz; i++)

Syntax error.

> ptr[i] = p[i];
> }
>
> //other members
>
> ~X() { delete ptr; ptr = NULL; }

Undefined behaviour. What has been allocated via new[] requires
delete[]. Besides, setting ptr to null is as gratuitous as the assert
before. ptr cannot be legally accessed anymore after the destructor has
executed.

> };
>
> class Y {
> X xobj

Missing semicolon.

>
> public:
> Y(int s, T *p) : xobj(s, p) { } //OK?
> //other members
> ~Y() { } //OK?
> };
>
> then
>
> int main(){
>
> ar[10] = {ten values};

Unknown identifer ar. If this is supposed to be its definition, where is
the type?

> Y yobj(10, ar); //problem here(?)
> ......
> .....

Syntax error.

> }
> What's the problem above?
> Thank you.

The main problem is that you submit ill-formed and incomplete code and
expect others to correct the obvious errors and guess the not so obvious
bits that are missing. Without knowing what T is, it is impossible to
say what is going on.

The only glaring runtime problem is the new[]/delete mismatch, but I
doubt that it would cause std::bad_alloc to be thrown (although with
undefined behaviour, anything is possible). The most likely cause is
inifinite recursion somewhere in the code you have not shown, which
causes the free store to be exhausted.


--
Gerhard Menzl

Non-spammers may respond to my email address, which is composed of my
full name, separated by a dot, followed by at, followed by "fwz",
followed by a dot, followed by "aero".


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On 16 avr, 23:43, mpho <tjab...(a)gmail.com> wrote:

> class X {
> int sz;
> T *ptr;
>
> public:
> X(int s, T *p) : sz(s), ptr(new T[s])
> {
> assert(ptr != NULL);
> for (int i = 0, i < sz; i++)
> ptr[i] = p[i];

ptr[i] = p[i] can throw.
If it does, you need to call delete[] on ptr.

> ~X() { delete ptr; ptr = NULL; }

You should use delete[], not delete. Calling delete on something
allocated with new[] is undefined behaviour.
ptr = NULL is also totally useless in a destructor.

By the way, the automatically defined operator= and copy constructor
will mess everything up. Either disable them, or write them to do deep-
copying.


> class Y {
> X xobj
>
> public:
> Y(int s, T *p) : xobj(s, p) { } //OK?
> //other members
> ~Y() { } //OK?
> };

That's OK, yes.


> ar[10] = {ten values};

That doesn't seem to be valid C++ syntax.


> Y yobj(10, ar); //problem here(?)

None at that line.

> What's the problem above?

How is a std::bad_alloc being raised a problem?
It could just means you're out of memory.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Chris Uzdavinis on
On Apr 16, 5:43 pm, mpho <tjab...(a)gmail.com> wrote:


> X(int s, T *p) : sz(s), ptr(new T[s])
> {
> assert(ptr != NULL);
> for (int i = 0, i < sz; i++)
> ptr[i] = p[i];
> }

Your assertion can never fail, since "new" throws a std::bad_alloc
when it fails. Therefore, the assertion is misleading and should
probably be removed.

> //other members
> ~X() { delete ptr; ptr = NULL; }
> };

Whoops! Your destructor must perform the array form of deletion:

delete [] ptr;

There is no need to set ptr to NULL afterwords, since as soon as we
exit the destructor, the object containing ptr no longer exists, and
its members can never be accessed again.

> int main(){
>
> ar[10] = {ten values};
> Y yobj(10, ar); //problem here(?)
> ......
> .....
>
> }
>
> What's the problem above?

1) ar has no type

2) "ten values" is pseudocode

3) Any uncaught exception (that can unwind the stack past main) will
cause std::terminate() to be called. Since there are no try/catch
blocks in your program, and you say an exception is occurring, it
should be of little surprise that your program terminates.

--
Chris


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: mpho on
On Apr 17, 7:13 pm, Chris Uzdavinis <cuz...(a)gmail.com> wrote:
> On Apr 16, 5:43 pm, mpho <tjab...(a)gmail.com> wrote:
>
> > X(int s, T *p) : sz(s), ptr(new T[s])
> > {
> > assert(ptr != NULL);
> > for (int i = 0, i < sz; i++)
> > ptr[i] = p[i];
> > }
>
> Your assertion can never fail, since "new" throws a std::bad_alloc
> when it fails. Therefore, the assertion is misleading and should
> probably be removed.
>
> > //other members
> > ~X() { delete ptr; ptr = NULL; }
> > };
>
> Whoops! Your destructor must perform the array form of deletion:
>
> delete [] ptr;
>
> There is no need to set ptr to NULL afterwords, since as soon as we
> exit the destructor, the object containing ptr no longer exists, and
> its members can never be accessed again.
>
> > int main(){
>
> > ar[10] = {ten values};
> > Y yobj(10, ar); //problem here(?)
> > ......
> > .....
>
> > }
>
> > What's the problem above?
>
> 1) ar has no type
>
> 2) "ten values" is pseudocode
>
> 3) Any uncaught exception (that can unwind the stack past main) will
> cause std::terminate() to be called. Since there are no try/catch
> blocks in your program, and you say an exception is occurring, it
> should be of little surprise that your program terminates.

{ edits: quoted signature and banner (see the end of this article) removed,
please don't quote extraneous material -- even if the clc++m banner is a very
fine one. -mod }

Dear all,

The obvious errors have really been mistypes and not deliberate. I
apologize. Thanks for the replies, the problem still persists. The
complete code, excluding the unnecessary stuff by your comments, is:

typedef T //something

class X {
int sz;
T *ptr;

public:
X(int s, T *p) : sz(s), ptr(new T[s])
{
for (int i = 0, i < sz; i++)
ptr[i] = p[i];
}

X(const X& other);
X& operator=(const X&);

~X() { delete [] ptr; }
};

class Y {
X xobj;

public:
Y(int s, T *p) : xobj(s, p) { }
//other members
~Y() { }
};

No problem with copy constructor and assignment.

int main(){

T ar[10] = {1,2,3,4,5,6,7,8,9,10};
Y yobj(10, ar); //problem here(?)
.......
......

}
No try/catch blocks in the program. Should this not work?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

First  |  Prev  |  Next  |  Last
Pages: 1 2 3
Prev: Namespace vs. isnan
Next: strcpy_s vs strcpy