Re: How to free this memory?

Discussion in 'C++' started by Alf P. Steinbach, Jan 13, 2012.

  1. On 13.01.2012 18:05, Bint wrote:
    > Hello, I am allocating some vertices to pass to a function, and then I want
    > to free the memory. How do I do this? The compiler is giving me warnings
    > when I do it this way:
    >
    > trivertex **vertices;
    >
    > vertices = new trivertex*[2];
    >
    > vertices[0] = new trivertex[100];
    > vertices[1] = new trivertex[50];
    >
    > .
    > .
    > .
    > delete vertices[0];
    > delete vertices[1];
    > delete vertices;
    >
    > I get this warning:
    > " 'delete' applied to a pointer-to-array type 'trivertex *' (aka 'double
    > (*)[3]') treated as delete"


    When you allocate with `new[]`, you should/must delete with `delete[]`.

    But you should not do use raw arrays and raw new.

    Use standard library containers such as `std::vector`.


    <code>
    #include <iostream>
    #include <vector>

    int main()
    {
    using namespace std;

    struct TriVertex { double x, y, z; };
    typedef vector<TriVertex> VertexVector;
    typedef vector<VertexVector> VertexVectorVector;

    VertexVectorVector vertices( 2 );
    vertices[0].resize( 100 );
    vertices[1].resize( 50 );
    }
    </code>


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Jan 13, 2012
    #1
    1. Advertising

  2. On 13.01.2012 19:07, Paul <pchrist wrote:
    >
    > How would you extract a pointer from the vector?


    You can just take the address of an element, like

    &v[0]

    or

    &front()

    for a non-empty vector v.

    The vector buffer has been guaranteed contiguous since C++03.

    With C++11 there is also a data() member function that has both const
    and non-const version, and that gives you &front() directly.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Jan 13, 2012
    #2
    1. Advertising

  3. On Jan 13, 10:07 am, "Paul" <pchrist<nospam>> wrote:
    > "Alf P. Steinbach" <> wrote in messagenews:jepq5f$bvj$...


    > > int main()
    > > {
    > >     using namespace std;

    >
    > >     struct TriVertex { double x, y, z; };
    > >     typedef vector<TriVertex>       VertexVector;
    > >     typedef vector<VertexVector>    VertexVectorVector;

    >
    > >     VertexVectorVector  vertices( 2 );
    > >     vertices[0].resize( 100 );
    > >     vertices[1].resize( 50 );
    > > }
    > > </code>

    >
    > Hi Alf
    > Thanks for the extra tips.
    > As an additional discussion point , how would you pass, for example, a
    > pointer to a vertex as a function argument when using the vector method?
    > For example:
    > void example_function(trivertex* arg){};
    >
    > example_function( vertices[0] ); /*No this won't convert to a pointer*/


    If example_function needs a pointer, give it one. Any of these will
    work, with a few caveats below.

    example_function( & vertices[0][0] );
    example_function( & vertices[0].front() );
    example_function( vertices[0].data() ); // C++11 only

    Caution: if vertices is empty, all of these give undefined behavior.
    Else, if vertices[0] is empty, the first two of the above give
    undefined behavior, and the third will probably give a pointer that
    example_function will try to do something bad with, since it has no
    'count' argument that could be specified as zero. And, if the
    trivertex class overloads unary operator& [but who does?] the first
    two of the above may possibly cause trouble. So be sure to check
    those conditions first.

    This is also assuming that example_function doesn't try to do anything
    silly with the pointer it's given like realloc(), free(), etc.

    (Note too that vector<bool> has a completely different implementation
    from any other vector<T>, such that you cannot get a useful bool* from
    it.)


    > I always feel I am entering dangerous territory when I start thinking about
    > pointers to vector elements.


    Not much to worry about: if you have a vector<T> where T is neither
    bool nor has its own unary operator&, a pointer to a single vector
    element can easily be acquired with & vec[index], and a pointer to the
    first element obtained as above is guaranteed to give you a bunch of
    objects that are contiguous in memory, just as if they were allocated
    with operator new[]. (But beware of polymorphic objects... don't put
    those in vectors.)


    > I am thinking of an iterator or something but I wonder if any iterator type
    > will convert to a pointer, or perhaps using addressof operator &. How would
    > you extract a pointer from the vector?


    Generally vector<T>::iterator is a typedef for T* (except in the
    special case vector<bool>), but this is not guaranteed (e.g. when
    compilers have debugging turned on).

    If you have only a vector<T>::iterator, AND you are sure it points to
    a valid object (is not a one-past-the-end or singular iterator), AND
    (yet again) T does not overload unary & and is not bool, you can get a
    pointer from it via

    vector<T>::iterator it = ...;
    T * ptr = & * it;

    - Kevin B. McCarty
    Kevin McCarty, Jan 13, 2012
    #3
  4. On Jan 13, 8:35 pm, "Paul" <pchrist<nospam>> wrote:
    > "Alf P. Steinbach" <> wrote in messagenews:jeptmu$2v8$...
    > > On 13.01.2012 19:07, Paul <pchrist wrote:



    > >> How would you extract a pointer from the vector?

    >
    > > You can just take the address of an element, like

    >
    > >   &v[0]

    >
    > > or

    >
    > >   &front()

    >
    > > for a non-empty vector v.

    >
    > > The vector buffer has been guaranteed contiguous since C++03.

    >
    > > With C++11 there is also a data() member function that has both const and
    > > non-const version, and that gives you &front() directly.

    >
    > Also i reply to Kevins post... I see the vector <bool> inconsistency and try
    > to avoid vector<bool>. But I still feel uncomfortable taking the address of
    > a vector element. There seems to be some dark looming uncomfortable danger
    > attached to this, I just can't put my finger on it.


    it really is safe!


    > I can see no harm on a single thread application however I wonder if there
    > may be implications on MT apps. For example if one thread has a pointer and
    > a different thread has modified the vector, in such a way that the pointer
    > is invalidated. What I am getting at is, even with STL containers,
    > programmers still need to tread carefully.
    >
    > In some appications, or programs,  the STL container is the perfect
    > solution. but I don't think this is always the case. I believe there is
    > still a large userbase who require the raw memory managment features of C++.
    > STL allocators are a very usefull, not to mention productive, feature of C++
    > but they are an abstract feature.


    whatever that means...

    > The basic laguage does not restrict its
    > useage to this abstract feature and for this we should be thankfull. C++ is
    > a powerfull programming language because it has so many different features,
    > we can use C++ as a Java like language(high level), or as a C like
    > language(low level) it has many different features and I think this is an
    > important aspect of its success.


    C++ has exceptions. Therefore you should write exception safe code. It
    is difficult to do this if you employ raw memory allocations.

    > I think the STL part of the C++ language is just one aspect of its many uses
    > and should not be emphasised to be any more important that the other
    > aspects. It woud be great if in the future we had one common programming
    > language , based on binary. But lets wait and see what happens with quantumn
    > computers, maybe binary is a bit retarded and we need to start thiking in
    > 3's, who knows.


    I'mnot sure why quantum compyer necessarily inolves trinary.

    > Actually quantum is all about two's( the atom is either in
    > the box or not in the box)


    not really! We only have a probability that the atom is in the box.

    > so maybe our knowledge of binary and quantumn fit together well.


    maybe not
    Nick Keighley, Jan 14, 2012
    #4
  5. On Jan 13, 6:48 pm, Kevin McCarty <> wrote:

    > Not much to worry about: if you have a vector<T> where T is neither
    > bool nor has its own unary operator&, a pointer to a single vector
    > element can easily be acquired with & vec[index], and a pointer to the
    > first element obtained as above is guaranteed to give you a bunch of
    > objects that are contiguous in memory, just as if they were allocated
    > with operator new[].  (But beware of polymorphic objects... don't put
    > those in vectors.)


    oops! Why not? It seems an obvious thing to want to do! Or rather
    pointers to POs. Is that ok?
    Nick Keighley, Jan 14, 2012
    #5
  6. On Jan 14, 2:19 am, Nick Keighley <>
    wrote:
    > On Jan 13, 6:48 pm, Kevin McCarty <> wrote:
    >
    > > Not much to worry about: if you have a vector<T> where T is neither
    > > bool nor has its own unary operator&, a pointer to a single vector
    > > element can easily be acquired with & vec[index], and a pointer to the
    > > first element obtained as above is guaranteed to give you a bunch of
    > > objects that are contiguous in memory, just as if they were allocated
    > > with operator new[].  (But beware of polymorphic objects... don't put
    > > those in vectors.)

    >
    > oops! Why not? It seems an obvious thing to want to do! Or rather
    > pointers to POs. Is that ok?


    STL containers of pointers of polymorphic objects, absolutely, that is
    fine. (Containers of unique_ptrs or shared_ptrs, even better, if
    you'd like the containers to have ownership of the objects.) If, as
    well as container ownership, you also want syntactic sugar to avoid
    having to use [unary] * or -> operators, consider boost::ptr_array,
    ptr_vector, etc.

    Putting polymorphic objects themselves directly into a container (or
    even a C-array or a block of new[]'ed up memory) is not a particularly
    good idea. A vector of base-class objects is unlikely to be very
    useful, and even if instantiable (if the base class is not abstract),
    is likely to encourage coding errors caused by slicing.

    A vector of derived-class objects could perhaps be useful if you need
    a bunch of copies of some objects known to have a specific fixed
    derived type. But code that creates a vector of derived objects can
    lead to the following mistake:

    vector<Derived> vder(2);
    Base * b = & vder[0]; // ok, get a pointer to the Base
    // portion of vder[0]
    b->doSomething(); // ok
    (++b)->doSomething(); // KABOOM

    Either is allowed by the language (if the base class is not abstract),
    and a very careful programmer could use such containers safely, but
    why make life complicated.

    - Kevin B. McCarty
    Kevin McCarty, Jan 16, 2012
    #6
  7. On Jan 13, 12:35 pm, "Paul" <pchrist<nospam>> wrote:

    > Also i reply to Kevins post... I see the vector <bool> inconsistency and try
    > to avoid vector<bool>. But I still feel uncomfortable taking the address of
    > a vector element. There seems to be some dark looming uncomfortable danger
    > attached to this, I just can't put my finger on it.
    > I can see no harm on a single thread application however I wonder if there
    > may be implications on MT apps. For example if one thread has a pointer and
    > a different thread has modified the vector, in such a way that the pointer
    > is invalidated. What I am getting at is, even with STL containers,
    > programmers still need to tread carefully.


    As always!

    Assuming the default vector allocator is used, the ways I can think of
    offhand that a pointer to an existing vector element may become
    invalid are

    a) the vector is resized to a smaller size, such that the pointer now
    points past the new end of the vector
    b) the vector is resized to a size larger than the original capacity,
    necessitating a memory re-allocation
    c) the vector is swapped with a temporary vector (the pointer now
    points into the temporary) which is then immediately destroyed
    d) the vector itself is destroyed (c is a special case of this)

    These can, of course, happen even in a single-threaded application if
    the programmer does not take care to avoid it. And if you run
    std::sort (etc.) on the vector, the object at the pointed-at location
    may become different than you expect...

    - Kevin B. McCarty
    Kevin McCarty, Jan 16, 2012
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sam
    Replies:
    2
    Views:
    2,223
    Dhruv
    Jun 27, 2003
  2. Replies:
    1
    Views:
    785
    Sebastian Millies
    Nov 2, 2006
  3. Panduranga Chary

    How memory function free() knows how much memory to free.

    Panduranga Chary, Dec 27, 2007, in forum: C Programming
    Replies:
    2
    Views:
    401
    Keith Thompson
    Dec 27, 2007
  4. george
    Replies:
    0
    Views:
    1,076
    george
    Aug 29, 2008
  5. mohammed_a_o
    Replies:
    0
    Views:
    254
    mohammed_a_o
    Nov 30, 2010
Loading...

Share This Page