0

I checked out this thread before posting here: How to avoid memory leaks when using a vector of pointers to dynamically allocated objects in C++?

Basically, I have some vectors of pointers that point to dynamically-allocated objects:

vector<MyType*> a;
a.push_back(new MyType());

These vectors are private instance variables of a few classes I'm writing, and the dynamically-allocated objects are destroyed in the classes' destructors by iterating thru the vectors and calling delete on each pointer.

It all works fine most of the time, but every once in a while a pointer in one of these vectors becomes invalid and causes a segfault when my code attempts to use it. I'm having trouble figuring out why these pointers occasionally break.

Are there any reasons why the dynamically-allocated object's address would change and cause the pointers to become invalid?

I can try to post actual code if necessary.

EDIT:

Ok I have a number of things going on here. There are two custom classes: VisaLane and VisaResource. VisaLane contains a vector<VisaResource*> of pointers to VisaResources created using new VisaResource().

Each VisaLane is also created using new VisaLane() whose pointers are stored in a vector<VisaLane*>.

This is one example of how the pointer gets corrupted. Item 0 in the vector has inaccessible members:

resources_  <3 items>   std::vector<VisaResource*>
    [0]     VisaResource
        function_   <not accessible>    std::string
        name_   <not accessible>    std::string
        state_  VisaResource::FREE  VisaResource::VisaResourceState
        value_  6998928 uint
    [1]     VisaResource
        function_   "lane_clksel"   std::string
        name_   "m1_lane0_clksel"   std::string
        state_  VisaResource::FREE  VisaResource::VisaResourceState
        value_  0   uint
    [2]     VisaResource
        function_   "lane_bypass"   std::string
        name_   "m1_lane0_bypass"   std::string
        state_  VisaResource::FREE  VisaResource::VisaResourceState
        value_  0   uint
visa_res_itr        __gnu_cxx::__normal_iterator<VisaResource**, std::vector<VisaResource*>>
Community
  • 1
  • 1
Drew Wiens
  • 124
  • 1
  • 8
  • I should add, I would use the nice auto pointers in the boost library, but my customer wants code only using the standard library and specifically asked for no boost code. Believe me I tried to convince them otherwise but they don't want to budge. – Drew Wiens Aug 16 '11 at 18:07
  • 2
    Is TR1 an option? That ships with most semi-recent compilers, and you can make a container of `std::tr1::shared_ptr`s which should solve your problem. – Kerrek SB Aug 16 '11 at 18:08
  • Suspects could include writes with bad addresses, and memory overwrites. – Andy Thomas Aug 16 '11 at 18:10

2 Answers2

1

You should not use raw pointers at all, Best way to avoid this is to use Smart pointers, Unique_ptr if you are not sharing your vector contents of shared_ptr if container elements are being shared across multiple enity's.

Using smart pointers will most likely help you get rid of your problem.

Other than that without seeing the source code, we can't comment on what is really going wrong.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • @Andrew Wiens: Almost every Most likely what you might be needing(as per need as mentioned in above answer) are: `std::tr1::shared_ptr` or `std::unique_ptr`, Do stay away from `auto_ptr` though, it is not designed for use with STl containers. – Alok Save Aug 16 '11 at 18:21
  • They must be copyable to be used with STL containers. `std::auto_ptr` can't be used because it swaps ownership on assignment and therefore can't be copied. – AJG85 Aug 16 '11 at 21:40
  • @Andrew: From the standard all recommended smart_pointers are supported by STL-containers. Note that auto_ptr, the oldest smart_pointer. is deprecated starting with C++0x and is not supported by containers! – MFH Aug 17 '11 at 00:53
1

You can make your own copyable reference counted smart pointer class for STL containers or use std::unique_ptr if your compiler supports C++0x. If it's slightly older you may have something in the std::tr1 namespace.

Alternately consider std::vector<MyType> as that container allocates contiguously on the heap anyway and will manage the memory for you. Avoid raw pointers at all cost.

AJG85
  • 15,849
  • 13
  • 42
  • 50