CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12
  1. #1
    Join Date
    Sep 2001
    Location
    Bilbao (spain)
    Posts
    110

    auto_ptr and arrays

    Hi all:

    I am using auto_ptr for ordinary pointers with no problem but i have a doubt about using it with arrays.

    I have an auto_ptr<char>, but what I assign to is a char[] instead of an unique char.
    If i use new, i must use delete for deletion, but if I use new[], i must use delete[], but here is auto_ptr the responsible of doing the delete. Wil the auto_ptr do the appropiate delete (normal or [])

    If the answer is no, do you have another alternative for guarantee deletion of array.

    NOTE: I cannot use vector<char> nor any other container. It must be a char array due to the API i use.

    Thanks in advance

  2. #2
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: auto_ptr and arrays

    You can't use auto_ptr for arrays, since it uses delete and not delete [].

    But I'm pretty sure you can actually use vector<char> (maybe even std::string, if you only need const char*).
    Code:
    void func(char *s)
    {
      // Your API function
    }
    std::vector<char> v;
    // Call it this way with the vector
    func(&v[0]);
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  3. #3
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: auto_ptr and arrays

    Quote Originally Posted by Carlos Martinez
    I have an auto_ptr<char>, but what I assign to is a char[] instead of an unique char.
    You can't. a char array is not an individual char.
    Quote Originally Posted by Carlos Martinez
    If i use new, i must use delete for deletion, but if I use new[], i must use delete[], but here is auto_ptr the responsible of doing the delete. Wil the auto_ptr do the appropiate delete (normal or [])
    auto_ptr will blindly call delete (and will never call delete[]), so you must never pass a pointer you've allocated with new[] to auto_ptr! Otherwise, behavior is undefined!

    Fortunately, you feeled it's wrong and posted on codeguru.

    Alternatives: std::vector<char>. It's guaranteed to allocate contiguous memory space.
    So, you are allowed to do things such as:
    Code:
    std::vector<char> arr(length);
    LegacyAPIwhichRequiresAPointerToAnArray(&arr[0], length); // This API may be GetTempPathA, or any other Win32 API working on char buffers.
    It is guaranteed to work!
    Beware, vector iterators are not guaranteed to be plain pointers... Which implies that in the above code, you can't replace &arr[0] with arr.begin().

    Alternatively, you can use boost::array
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

  4. #4
    Join Date
    Sep 2001
    Location
    Bilbao (spain)
    Posts
    110

    Re: auto_ptr and arrays

    It's simple, but i have a doubt.
    I suppose internat representation of vector to be an array, but C++ standard imposes it?
    I fear it could not be an array in all implementations.

    Quote Originally Posted by Yves M
    You can't use auto_ptr for arrays, since it uses delete and not delete [].

    But I'm pretty sure you can actually use vector<char> (maybe even std::string, if you only need const char*).
    Code:
    void func(char *s)
    {
      // Your API function
    }
    std::vector<char> v;
    // Call it this way with the vector
    func(&v[0]);

  5. #5
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: auto_ptr and arrays

    It is guaranteed to behave like an array. It doesn't have to be one, mainly because it could be allocated with something different from new []. It could even use parts of a static array in some sort of pool. But what is guaranteed is that elements are stored contiguously (i.e. no gaps) and that &v[0] returns a pointer to the beginning of the element array. So the memory layout is guaranteed to be the same as for an array and you can get a pointer to the first element.
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  6. #6
    Join Date
    Sep 2001
    Location
    Bilbao (spain)
    Posts
    110

    Re: auto_ptr and arrays

    Quote Originally Posted by SuperKoko
    Alternatives: std::vector<char>. It's guaranteed to allocate contiguous memory space.
    So, you are allowed to do things such as:
    Code:
    std::vector<char> arr(length);
    LegacyAPIwhichRequiresAPointerToAnArray(&arr[0], length); // This API may be GetTempPathA, or any other Win32 API working on char buffers.
    It is guaranteed to work!
    Beware, vector iterators are not guaranteed to be plain pointers... Which implies that in the above code, you can't replace &arr[0] with arr.begin().
    How can I initialize a vector efficiently from a const char*?
    Code:
    int length=strlen(myStr);
    myVector.resize(length);
    memcpy(&myVector[0],myStr,length);
    I want to do something shorter, like I do with strings:
    Code:
    string myString(myStr,strlen(myStr));
    I have not see a constructor for vector from a pointer and length.

    I could use string instead of vector, but can I do the same? Can use them in the same way?
    What I want is an alternative for buffers in (char*,length) format (memory safe). Vector is a good alternative but I miss a simpler initialization from a buffer.

    NOTE: myStrings are not null terminated strings (are binary)

  7. #7
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: auto_ptr and arrays

    Use the "pair of iterators" constructor:
    Code:
    const char* str = "Hello World";
    const int len = strlen(str);
    vector<char> vec(str, str + len);
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  8. #8
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: auto_ptr and arrays

    Code:
     std::vector<char> vct( mystr, mystr+length);
    Har Har

  9. #9
    Join Date
    Sep 2001
    Location
    Bilbao (spain)
    Posts
    110

    Re: auto_ptr and arrays

    I knew the constructor from iterators, but I didn't know pointers could be uses instead of iterators.

    Thanks.

    Quote Originally Posted by Graham
    Use the "pair of iterators" constructor:
    Code:
    const char* str = "Hello World";
    const int len = strlen(str);
    vector<char> vec(str, str + len);

  10. #10
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: auto_ptr and arrays

    Quote Originally Posted by Carlos Martinez
    I knew the constructor from iterators, but I didn't know pointers could be uses instead of iterators.

    Thanks.
    The pointers are the iterators for C style arrays.
    Har Har

  11. #11
    Join Date
    Feb 2005
    Location
    "The Capital"
    Posts
    5,306

    Re: auto_ptr and arrays

    Well, as already said, you cannot use auto_ptr for dynamic array allocations. But it is trivial enough to write as long as it is to be as novice as auto_ptr. Take up any sample implementation of auto_ptr and replace the destructions (occurences of delete) with delete[] operator. I hope this should work, haven't tried out so may be you would need to tweak it a bit at a few more places in the implementation. But that is the main difference that exists. This would then become something like boost::scoped_array.

    Moreover, take a look at: shared_array @ boost : http://www.boost.org/libs/smart_ptr/smart_ptr.htm

    I am sure you can use vector<char>. They as well as std::string are quite okay for C-API use (esp vectors). The layout is guranteed to be compatible, though in case of strings it can be problematic due to different implementations (reference counted etc) but vectors for sure you can!

  12. #12
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: auto_ptr and arrays

    Quote Originally Posted by Yves M
    It is guaranteed to behave like an array. It doesn't have to be one, mainly because it could be allocated with something different from new [].
    <pedantic note>
    Well... There are two possible definitions of array: Either it's an object of type array such as int[3]... In that case, new[] can't allocate an array... At best, you can allocate a chunck of chars, and cast the pointer returned to an int(*)[3] or another pointer to array, and then, the effective type of the memory will become int[3] as soon as any memory access or memory write is done in the light of this array.
    Another, more-common, less standard-ish definition of array is simply: block of memory where elements are in a contiguous layout, without gaps. In the latter case, new[] doesn't create more an array than any other mean that creates a contiguous memory layout.
    </pedantic note>
    I want to do something shorter, like I do with strings:
    Well... Whenever you get something like that, you should think about creating functions (OOP is supposed to be more flexible than good old procedural programming, and that stuff is perfectly done with good old procedural programming!)
    Code:
    std::vector<char> ToCharVector(const char* str) { // returns a vector<char> which includes the nul terminator!
      return std::vector<char>(str, str+strlen(str)+1);
    }
    void AssignToCharVector(std::vector<char>& v,const char* str) { // another function which might be useful
      std::size_t ln=strlen(str)+1;
      v.resize(ln);
      std::copy(str, str+ln, v.begin()); // memcpy would be ok as well.
    }
    "inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
    Club of lovers of the C++ typecasts cute syntax: Only recorded member.

    Out of memory happens! Handle it properly!
    Say no to g_new()!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured