Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dynanic Memory

48 views
Skip to first unread message

Bill Cunningham

unread,
Jan 26, 2016, 1:24:49 PM1/26/16
to
I just wanted to ask someone famailiar with C++ this question. just
asked this nextdoor in clc so I will get clc++'s take. In C one initializes
a dynamic array as such,

int *p;
p=malloc(10*sizeof(int));

And this works for its' purpose. How is dynamic memory handled in C++? In an
easier manner?

Bill


Victor Bazarov

unread,
Jan 26, 2016, 1:26:56 PM1/26/16
to
Ease is in the eye of the beholder. In C++ it is done either exactly
the same way (since 'malloc' is part of C++ just as it is part of C), or

int *p = new int[10];

V
--
I do not respond to top-posted replies, please don't ask

Alf P. Steinbach

unread,
Jan 26, 2016, 1:40:19 PM1/26/16
to
vector<int> v( 10 );


Cheers & hth,

- Alf


Alf P. Steinbach

unread,
Jan 26, 2016, 1:53:53 PM1/26/16
to
On 1/26/2016 7:26 PM, Victor Bazarov wrote:
> On 1/26/2016 1:24 PM, Bill Cunningham wrote:
>> I just wanted to ask someone famailiar with C++ this question. just
>> asked this nextdoor in clc so I will get clc++'s take. In C one
>> initializes
>> a dynamic array as such,
>>
>> int *p;
>> p=malloc(10*sizeof(int));
>>
>> And this works for its' purpose. How is dynamic memory handled in C++?
>> In an
>> easier manner?
>
> Ease is in the eye of the beholder. In C++ it is done either exactly
> the same way (since 'malloc' is part of C++ just as it is part of C),

Well in C++ one has to cast the result of `malloc` unless a `void*` is
what one desires, while in C one shouldn't cast the result lest one
inadvertently generates an implicit declaration when the relevant
include is missing. This difference in the advice or best practice for
the two languages is due to different rules for implicit conversions,
and different rules for implicit declarations. Of course, using `malloc`
is usually not best practice in C++ anyway, but it can be necessary due
to requirements of C APIs, or for use of `realloc`.


> or
>
> int *p = new int[10];

Yes.

One difference here is that this defaults to throwing an exception when
memory can't be allocated, while malloc returns a nullpointer, so at
least when memory exhaustion is an issue one can't just replace a C
`malloc` call with a C++ `new` expression and have equivalent C++ code.

• • •

All those differences noted, I think in C++ one should generally prefer
standard library containers when possible, and in this case, just use
`vector<int>`,

vector<int> v( 10 );

which automates all that memory management, is more robust, and provides
much useful & convenient functionality.

I'm pretty sure you agree with that but just didn't put that in your
short & fast answer.

Cheers,

- Alf

Paavo Helde

unread,
Jan 26, 2016, 2:01:05 PM1/26/16
to
Either

std::array<int, 10> arr;

or

std::vector<int> vec(10);

The first provides a fixed-size buffer whereas the second can easily
grow and shrink at run-time.

hth
Paavo

Chris Vine

unread,
Jan 26, 2016, 2:02:27 PM1/26/16
to
On Tue, 26 Jan 2016 13:26:43 -0500
Victor Bazarov <v.ba...@comcast.invalid> wrote:
> On 1/26/2016 1:24 PM, Bill Cunningham wrote:
> > I just wanted to ask someone famailiar with C++ this
> > question. just asked this nextdoor in clc so I will get clc++'s
> > take. In C one initializes a dynamic array as such,
> >
> > int *p;
> > p=malloc(10*sizeof(int));
> >
> > And this works for its' purpose. How is dynamic memory handled in
> > C++? In an easier manner?
>
> Ease is in the eye of the beholder. In C++ it is done either exactly
> the same way (since 'malloc' is part of C++ just as it is part of C),
> or
>
> int *p = new int[10];
>
> V

Not quite exactly the same way, as in C++ for safety reasons there is no
implicit cast from void* to int*, so it would be:

p=static_cast<int*>(malloc(10*sizeof(int));

However in C++ you would in practice use std::make_unique() instead of
the new expression or malloc(), or as someone else has suggested, you
would use std::vector, and move them as necessary.

Chris

Bill Cunningham

unread,
Jan 26, 2016, 2:08:18 PM1/26/16
to

"Paavo Helde" <myfir...@osa.pri.ee> wrote in message
news:sr-dnfJEa7z5XzrL...@giganews.com...
One thing is in what little C++ I have done, it's been small things. And
I believe that's when the 'using' directive can be used. In all my .cc code
I've done before I have...

#include <iostream>
using std namespace;

So I've never done anything with namespaces. Nor in C.

Bill


Chris Vine

unread,
Jan 26, 2016, 2:11:02 PM1/26/16
to
The OP said he was interested in "dynamic memory", whereas std::array is
the equivalent of a C array allocated on the stack. This is compounded
by the fact that, because it is stack allocated, it is not a movable
container. A move of std::array will try and move every element, or
copy them if the element type has no move constructor or move
assignment operator (as the case may be).

std::vector is as you say a direct analogue of malloc(), because its
memory is allocated dynamically and is moveable with a pointer swap.

Chris

Bill Cunningham

unread,
Jan 26, 2016, 2:11:03 PM1/26/16
to

"Paavo Helde" <myfir...@osa.pri.ee> wrote in message
news:sr-dnfJEa7z5XzrL...@giganews.com...
> On 26.01.2016 20:24, Bill Cunningham wrote:
>> I just wanted to ask someone famailiar with C++ this question. just
>> asked this nextdoor in clc so I will get clc++'s take. In C one
>> initializes
>> a dynamic array as such,
>>
>> int *p;
>> p=malloc(10*sizeof(int));
>>
>> And this works for its' purpose. How is dynamic memory handled in C++? In
>> an
>> easier manner?
>
> Either
>
> std::array<int, 10> arr;

Ok with the static buffer here, is arr or array the name of the array?
One must be a directive or command.

> or
>
> std::vector<int> vec(10);

Ok. the above is dynamic. Runtime so there's never any buffer overflows
with the above code?

Chris Vine

unread,
Jan 26, 2016, 2:18:10 PM1/26/16
to
On Tue, 26 Jan 2016 14:10:51 -0500
"Bill Cunningham" <nos...@nspam.invalid> wrote:
[snip]
> > or
> >
> > std::vector<int> vec(10);
>
> Ok. the above is dynamic. Runtime so there's never any buffer
> overflows with the above code?

Sure there can be buffer overflow if you use direct access to its
elements with operator[](), because as constructed it has a size of 10
ints. To add more elements than 10 you would need to use
std::vector::push_back().

If you want to avoid buffer overflow when setting elements use the
default constructor and then insert elements using that method. If you
want to avoid buffer overflow when reading elements you can use
std::vector::at() instead of operator[](), in which case you will get
an exception if you try to access a non-existent element.

Chris

Bill Cunningham

unread,
Jan 26, 2016, 2:26:10 PM1/26/16
to

"Chris Vine" <chris@cvine--nospam--.freeserve.co.uk> wrote in message
news:20160126191...@bother.homenet...

> Sure there can be buffer overflow if you use direct access to its
> elements with operator[](), because as constructed it has a size of 10
> ints. To add more elements than 10 you would need to use
> std::vector::push_back().
>
> If you want to avoid buffer overflow when setting elements use the
> default constructor and then insert elements using that method. If you
> want to avoid buffer overflow when reading elements you can use
> std::vector::at() instead of operator[](), in which case you will get
> an exception if you try to access a non-existent element.

Oh I see. Well I kinda wondered if that was to good to be true. I
thought runtime memory management that's smart! Now I've never seen the
scoping operator used twice as above. I've also never seen at() or
operator[](). Guess I have some things to check into.

Bill


Scott Lurndal

unread,
Jan 26, 2016, 2:50:32 PM1/26/16
to
Victor Bazarov <v.ba...@comcast.invalid> writes:
>On 1/26/2016 1:24 PM, Bill Cunningham wrote:
>> I just wanted to ask someone famailiar with C++ this question. just
>> asked this nextdoor in clc so I will get clc++'s take. In C one initializes
>> a dynamic array as such,
>>
>> int *p;
>> p=malloc(10*sizeof(int));
>>
>> And this works for its' purpose. How is dynamic memory handled in C++? In an
>> easier manner?
>
>Ease is in the eye of the beholder. In C++ it is done either exactly
>the same way (since 'malloc' is part of C++ just as it is part of C), or
>
> int *p = new int[10];
>

And in neither case is the dynamic array "initialized". The pointer
will have a valid value, but the contents to which it points are
UNDEFINED.

Paavo Helde

unread,
Jan 26, 2016, 2:58:08 PM1/26/16
to
Automatically growing the array upon out-of-range access would probably
just hide bugs. On the other hand, there are other containers which
indeed add missing elements automatically. E.g.


std::map<int, int> buff;
buff[0] = 1;
buff[100000] = 2;

Note that here the 'buff' container contains 2 elements (not 100001).

About vector details see e.g.

http://www.cplusplus.com/reference/vector/
http://www.cplusplus.com/reference/vector/vector/operator%5B%5D/
http://www.cplusplus.com/reference/vector/vector/at/

hth
Paavo


Victor Bazarov

unread,
Jan 26, 2016, 3:36:20 PM1/26/16
to
<shrug> I presumed the OP asked how to *allocate* it and use a wrong
term. Since Bill stated that the 'malloc' approach "worked", the
solution offered had supposedly the same effect.

Vir Campestris

unread,
Jan 26, 2016, 6:18:28 PM1/26/16
to
On 26/01/2016 19:25, Bill Cunningham wrote:
> Oh I see. Well I kinda wondered if that was to good to be true. I
> thought runtime memory management that's smart! Now I've never seen the
> scoping operator used twice as above. I've also never seen at() or
> operator[](). Guess I have some things to check into.

What nobody has mentioned is that malloc must have a matching free. And
it must be there on _all_ the error paths.

Whereas with the C++ methods you just create your vector, and when it
goes out of scope the language cleans it up for you.

Andy

Christopher Pisz

unread,
Jan 26, 2016, 6:25:49 PM1/26/16
to
Don't make a habit of auto typing using namespace std in every cpp file
without it actually running through your mind that "I intend to lookup
these names in the std namespace". One day you'll run into a case where
you don't want to and are actually after something else.



--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---

Juha Nieminen

unread,
Jan 27, 2016, 5:56:53 AM1/27/16
to
Bill Cunningham <nos...@nspam.invalid> wrote:
> One thing is in what little C++ I have done, it's been small things. And
> I believe that's when the 'using' directive can be used. In all my .cc code
> I've done before I have...
>
> #include <iostream>
> using std namespace;

What benefit do you get by doing that?

(And no, avoiding the "std::" prefix is not a benefit. I could write a
lengthy essay on why.)

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

JiiPee

unread,
Jan 27, 2016, 7:53:05 AM1/27/16
to
but you agree, its faster and shorter though? (varmasti olet samaa
mielta etta on lyhyaempi? :) )
like when teaching, less confusion maybe?

JiiPee

unread,
Jan 27, 2016, 7:56:08 AM1/27/16
to
On 26/01/2016 19:57, Paavo Helde wrote:
> On 26.01.2016 21:25, Bill Cunningham wrote:
>> "Chris Vine" <chris@cvine--nospam--.freeserve.co.uk> wrote in message
>> news:20160126191...@bother.homenet...
>>
>>> Sure there can be buffer overflow if you use direct access to its
>>> elements with operator[](), because as constructed it has a size of 10
>>> ints. To add more elements than 10 you would need to use
>>> std::vector::push_back().
>>>
>>> If you want to avoid buffer overflow when setting elements use the
>>> default constructor and then insert elements using that method. If you
>>> want to avoid buffer overflow when reading elements you can use
>>> std::vector::at() instead of operator[](), in which case you will get
>>> an exception if you try to access a non-existent element.
>>
>> Oh I see. Well I kinda wondered if that was to good to be true. I
>> thought runtime memory management that's smart! Now I've never seen the
>> scoping operator used twice as above. I've also never seen at() or
>> operator[](). Guess I have some things to check into.
>
> Automatically growing the array upon out-of-range access would
> probably just hide bugs. On the other hand, there are other containers
> which indeed add missing elements automatically. E.g.
>
>
> std::map<int, int> buff;
> buff[0] = 1;
> buff[100000] = 2;
>
> Note that here the 'buff' container contains 2 elements (not 100001).

somebody said in a conference video , concpp 2014, that map is bad and
should not be used. performance issues... donno....

Bill Cunningham

unread,
Jan 27, 2016, 9:09:13 AM1/27/16
to

"Juha Nieminen" <nos...@thanks.invalid> wrote in message
news:n8a7p1$k7f$1...@adenine.netfront.net...

> What benefit do you get by doing that?
>
> (And no, avoiding the "std::" prefix is not a benefit. I could write a
> lengthy essay on why.)

Well I'm not dealing with different namespaces. I never have. If your going
to do that, the scoping operator with std namespace would be a good habit. I
want to learn the standard namespace.

Bill


Bill Cunningham

unread,
Jan 27, 2016, 9:10:54 AM1/27/16
to

"Vir Campestris" <vir.cam...@invalid.invalid> wrote in message
news:0a6dnRcwOoElYzrL...@brightview.co.uk...

> What nobody has mentioned is that malloc must have a matching free. And it
> must be there on _all_ the error paths.

Yes indeed.

> Whereas with the C++ methods you just create your vector, and when it goes
> out of scope the language cleans it up for you.

How does it do that?

Bill


JiiPee

unread,
Jan 27, 2016, 9:27:46 AM1/27/16
to
I guess the issue is that even if you do not use now, you might use it
later on in the same project. So they are there ready.

Paavo Helde

unread,
Jan 27, 2016, 9:58:46 AM1/27/16
to
On 27.01.2016 14:55, JiiPee wrote:
>
> somebody said in a conference video , concpp 2014, that map is bad and
> should not be used. performance issues... donno....

If you need the functionality of std::map, then I am sure std::map is as
good as it gets. If you don't need this functionality, then you use
something else, like std::vector or std::unordered_map().

In any case, premature optimization is the root of all the evil as we
know, first get the code correct and clear, then if the performance is
not good, profile and fix the problems. Without working code you even
cannot know where the bottlenecks are, and if the code is not clear it
would be very difficult to add the needed optimizations.

Cheers
Paavo

Victor Bazarov

unread,
Jan 27, 2016, 10:01:06 AM1/27/16
to
When the automatic object of type std::vector<...> goes out of scope,
the d-tor is called, and *in it* the dynamic memory (if any) is freed.

Paavo Helde

unread,
Jan 27, 2016, 10:01:30 AM1/27/16
to
RAII (https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization).

One of the most important strengths of C++, IMO.

Chris Vine

unread,
Jan 27, 2016, 3:51:31 PM1/27/16
to
In case Bill is confused by this and thinks that this is no advantage
over static allocation, the rider should be added to the last statement
"if you have not moved ownership of the dynamic memory elsewhere".

You can move the memory held by a vector to another vector. If you do
that the original vector will safely destroy itself when it goes out of
scope but not interfere with the ownership of its successor.

Chris

Victor Bazarov

unread,
Jan 27, 2016, 5:09:47 PM1/27/16
to
On 1/27/2016 3:51 PM, Chris Vine wrote:
> On Wed, 27 Jan 2016 10:00:52 -0500
> Victor Bazarov <v.ba...@comcast.invalid> wrote:
>> On 1/27/2016 9:10 AM, Bill Cunningham wrote:
>>> "Vir Campestris" <vir.cam...@invalid.invalid> wrote in message
>>> news:0a6dnRcwOoElYzrL...@brightview.co.uk...
>>>
>>>> What nobody has mentioned is that malloc must have a matching
>>>> free. And it must be there on _all_ the error paths.
>>>
>>> Yes indeed.
>>>
>>>> Whereas with the C++ methods you just create your vector, and when
>>>> it goes out of scope the language cleans it up for you.
>>>
>>> How does it do that?
>>
>> When the automatic object of type std::vector<...> goes out of scope,
>> the d-tor is called, and *in it* the dynamic memory (if any) is freed.
>
> In case Bill is confused by this and thinks that this is no advantage
> over static allocation, the rider should be added to the last statement
> "if you have not moved ownership of the dynamic memory elsewhere".

I am not sure the additional "rider" is needed given the "(if any)" is
already there. But if you feel it makes it /clearer/ to Bill, by all
means...

>
> You can move the memory held by a vector to another vector.

... which effectively takes the memory in the given vector and by the
time its d-tor executes, there is no dynamic memory *for it* to free.
The same result might be achieved by clearing the vector (the ownership
of said dynamic memory is optionally returned to the free store).

> If you do
> that the original vector will safely destroy itself when it goes out of
> scope but not interfere with the ownership of its successor.
>
> Chris
>

0 new messages