Re: Strategies for avoiding new?

From: Josh Sebastian (usenet_at_inglorion.com)
Date: 02/23/04


Date: Sun, 22 Feb 2004 21:00:50 -0500

On Mon, 23 Feb 2004 01:01:04 GMT, Wolfie <dbgbdwolf@gte.net> wrote:

> Josh Sebastian wrote:
>
>> On Sun, 22 Feb 2004 23:57:16 GMT, Wolfie <dbgbdwolf@gte.net> wrote:
>
>>> I'm just wondering if there's an alternative to using new
>>> in these general cases where you don't know the exact number
>>> of items to store in the container at design time (and/or
>>> don't want to create a huge container and individual items
>>> one may not need.)
>
>> Is there a reason you're storing pointers instead of the objects
>> themselves?
>
> Lack of knowledge? :)
>
> Let me give an example:
>
> A UNIX password file has an unknown number of entries. A user
> class is easily defined which represents one of those entries.
> A amp can then be used to represent the password file itself
> (or, more appropriately, all the system's users.)
>
> I don't know how many user classes I'll need. A growable
> container is important (which is why I use map or whatever.)
> But how do I avoid new for each individual object I have to
> create?

Create the objects on the stack. Instead of doing

   Type* pobj = new Type;

just do

   Type obj;

> IOW:
> open password file;
> read data into a string;
> while (more_data) {
> ptr = new user(data);

user obj(data);

> add ptr to map;

add (copy of) obj to map;

> read data into a string;
> }
>
> go do other stuff, which may change the object.
> (For instance, now that I have their information,
> I can determine (and store in that user object)
> the amount of disk space they're using and a host
> of other information.)
>
> Is it "proper" to only use one object? For example,
>
> while (more_data) {
> obj.load(string);
> store obj in map;
> read data into a string;
> }

It's appropriate to limit the scope of names as narrowly as possible. It's
also good RAII ("resource acquisition is initialization"; roughly: using
constructors and destructors) practice to define an object only when you
have some data to put in it. So the above loop might have real C++ code
like

   std::vector<std::string> users;
   // ...
   std::string line;
   while(getline(std::cin, line)) {
     User u(line); // create a user from the data
     users.push_back(u); // add the user to the vector
     }

> and then, in other areas of the code, get a *copy* of
> the object from the map, modify it, and place it back?

No. C++ has "reference" types, so you can get a reference to the object
 from the container and manipulate it directly. Look at the doc for the
operator[] function for map (or vector, like I used above). It'll look
something like

   value_type& operator[](size_type sz); // for vector

The `&' character after the type name means it's a reference to a
value_type. (In std::vector, value_type is a typedef for the type that's
stored in the vector. In the snippet I used above, it would be
std::string.)

So after my snippet, say three users were loaded. You could say

   users[1].change_name("joe");

To change the second user's name to "joe". Or something. No copies are
ever made: you're manipulating the object stored in the container directly.

> IOW, does the map actually allocate it's *own* memory
> for each object, making *my* allocation unnecessary?

Yes.

> In C, I'd have to build a linked list (or some other
> container) and I'd store a pointer to a struct I'd
> allocated. I'm (essentially) doing the same thing,
> except with STL containers instead of a linked list.
>
> Make more sense?

Yes... you're doing more work than necessary. :-}

Sometimes an object won't allow you to make a copy of it (streams, for
example), in which case you'd have to do something like what you were
doing. But most of the time, using pointers is unnecessary.

-- 
Josh


Relevant Pages

  • Re: Ada.Containers.Indefinite_Ordered_Maps of gcc 4.0.1 has bug ?
    ... Empty_Map: constant Map; ... No_Element: constant Cursor; ... function Length (Container: Map) return Count_Type; ... pragma Inline; ...
    (comp.lang.ada)
  • Re: inheritance from STL-container
    ... First of all, you've shown the DBC ... number of algorithms are implemented as member functions. ... container wouldn't allow you to add the DBC stuff to them anyway. ... Generally smart pointers. ...
    (microsoft.public.vc.stl)
  • Re: Strategies for avoiding new?
    ... >allocate and store in a container" strategy. ... So whether you store pointers or values in the container depends upon what ...
    (alt.comp.lang.learn.c-cpp)
  • Re: using map, list etc. in const methods
    ... and you need to make sure that the map doesn't hold ... how are your pointers allocated and deleted? ... need to read a couple of good books that deal with memory management issues. ... At the moment I'm just using lists, ...
    (comp.lang.cpp)
  • Re: Base class referring to inheritor
    ... particular type implemented by the interface. ... the 'map' function is supposed to map a function ... That container is a Mappable: ... I would like to write a base class in the following way: ...
    (microsoft.public.dotnet.languages.csharp)