12

I've started a project in C++. Memory management in this language is new to me.

I used to create objects with new () and then pass around pointers and while it worked, it was a pain to debug and people looked at me funny when they saw the code. I am quite proud of the fact that it didn't leak or segfault (once fixed), but it really was a lot of effort.

list <struct Connection *> users;

struct Connection * accept_connection (const char *name) {
  struct Connection * new_node = new Connection ();
  new_node->_data = ... // whatever, set it up here
  return new_node;
}

struct Connection * new_user = accept_connection (const char *name);
users.append (new_user);

So I have a new strategy for this next version of the project. So far what I am doing is creating objects with new () and assigning them a unique integer ID number. I then store the object in a hashed table using the ID as a key. Now items are stored and passed around by the integer ID number and when you do need to de-reference it, you go to the hash table and it returns you either thing * or NULL. Hence I no longer experience pointer errors but the speed of the code is somewhat reduced.

typedef unsigned long ID_Number;

// create a user and return the ID
ID_Number create_user () {
  ID_Number new_id = assign_unique_id ();
  struct User * node = new User ();
  node->_id = new_id;
  node->_data = ... // whatever, set it up here
  add_to_users_dict (new_id, node);
  return new_id;
}

list <ID_Number> users;

for_each (users.begin(), users.end(), process_user);

void process_user (ID_Number i) {
  struct User * u_ptr = lookup_user_dict (i);
  if (u_ptr == NULL) {
    // not found in dict
    // somehow this guy was deleted
  } else {
    // we can do stuff with this guy
  }
}

Now I am sort of familiar with the basic tenets of programming but being a self-taught hobbyist I am not familiar with the industry practices and tools. What I am basically asking for, is guidelines on memory management:

1) What am I doing right or wrong?

2) Are there any packages or libraries I can use that would help me?

3) What the the standard practices of the industry?

4) Basically what should I be googling or buying for kindle etc?

Today I usually use Python, it does handle a lot of "back end" stuff for me, but I need C or C++ (I guess I'm using plain C plus the stdc++ libs, I am not quite sure where the overlap between the languages is - I just know g++ compiles it fine) for this one particular project for speed/performance reasons: although I suspect some maths genius could provide algorithmic fixes that would speed it no end, though that's a separate question.

  • 2
    Start by looking at `shared_ptr`. – Mark Ransom May 22 '12 at 16:05
  • The first tool I'd use is valgrind: http://valgrind.org/docs/manual/QuickStart.html – Anycorn May 22 '12 at 16:05
  • 11
    Look up RAII. This is kinda insane. – Edward Strange May 22 '12 at 16:05
  • 5
    Sounds like you'd benefits lots from [a good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – R. Martinho Fernandes May 22 '12 at 16:08
  • possible duplicate of [Memory management in C++](http://stackoverflow.com/questions/76796/memory-management-in-c) – Mike Seymour May 22 '12 at 16:08
  • @R Martinho Fernandes - Can you recommend one of those? I think I need RAII and factories. I will leave it to the judgement of those that know C++ better than I do, but I'd get kind of bored with a "How to compile hello world" book. Granted that I am not an expert in C++ and there might be things I don't know of, that I don't know that I need to know. –  May 22 '12 at 21:41

4 Answers4

10

The best answer I can give, is you shouldn't use pointers in the traditional way. C++11 has changed the way the programmer deals with memory management.

Rather than explaining things that have already been explained in detail by people far more intelligent than myself I will just provide some links.

The first you should look at is Herb Sutter's Article Elements of Modern C++ Style Then check out the video by Bjarne Stroustrup C++11 Style

If you are able to use the new C++11 standard you should, it makes memory management much cleaner than before.

b00t
  • 409
  • 3
  • 10
Kyle C
  • 1,627
  • 12
  • 25
2

What am I doing right or wrong?

You've essentially created a system that uses handles to refer to objects instead of direct pointers. This can be appropriate for some scenarios. Operating systems often use handles when the OS "owns" the object and manages its lifetime but allows a client to refer to it.

Are there any packages or libraries I can use that would help me?

The standard library in modern C++ has shared_ptr and unique_ptr, which are smart pointers that manage the lifetime of the dynamic objects. They are a great way to use RAII.

What the the standard practices of the industry?

The de facto standard in C++ is RAII -- resource allocation is initialization. RAII ties allocation to constructors and deallocation to destructors. Since C++ has solid guarantees about how and when c'tors and d'tors execute, this gives you a perfect way to manage object lifetimes with no leaks. The smart pointers, shared_ptr and unique_ptr, also make the ownership of the object explicit.

Basically what should I be googling or buying for kindle etc?

Search for RAII.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
2

Your first error is to use new.

Dynamic memory is rarely needed, and it is even rarer than it is needed "directly": most dynamically allocated objects live within a container (like vector or map).

Your second error is not to use constructors, once you understand what are class invariants and how constructors enable them, then you will be able to take advantage of RAII (Resource Acquisition Is Initialization) and stop coding in C.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • I started looking at RAII - wrap the ctor/dtor so the dtor is automatically called when the wrapper is removed from the stack. So with RAII how do I put a single instance of a thing into two different lists? I'd have to use references? How then do I stop list B from iterating over something list A said to delete? It seems I'd have to either add a "is_deleted_skip_me" boolean into each struct (and cull them periodically) or I need to keep cleaning my lists whenever any single list changes? -- EDIT: I begin to the think the application is poorly designed if it needs so many separate lists. –  May 22 '12 at 17:31
  • @gecko: many interdependent lists looks bad, though I do not know your constraints. Can you not copy the information so that each list has its own copy ? Otherwise, there is always the possibility of using a `shared_ptr`, but it does open the door to some difficulties down the road. – Matthieu M. May 22 '12 at 17:44
  • Boxes (data object) inside a container (itself a different instance of the same struct - only name and capacity differ), so the container has a list of its contents. An agent remembers the last N items it touched. So if an agent puts boxes into a container, that's 2 lists with the same items. –  May 22 '12 at 19:18
  • @gecko: I can see two ways out of this. The first is nearly shared ownership (`shared_ptr`, with the agent taking a `weak_ptr` to it), the second is a notification based mechanism. You can make the agent an `Observer` (it is a design pattern) over a box and have the box notify its observers of its impending destruction so that they unregister it before it is effectively destroyed. This is the difference between asynchronous and synchronous detection of destruction, the trade-off vary. – Matthieu M. May 22 '12 at 20:06
1

1) What am I doing right or wrong?

You're not using the Resource Acquisition Is Initialization (RAII) idiom or modern C++ ownership semantics.

2) Are there any packages or libraries I can use that would help me?

If you actually need to pass pointers around you can use std::unique_ptr and std::shared_ptr. But before going to that you should learn about making your own objects behave as resource owners with RAII semantics.

3) What the the standard practices of the industry?

4) Basically what should I be googling or buying for kindle etc?

RAII

bames53
  • 86,085
  • 15
  • 179
  • 244