Thread: Which smart pointer to use?

  1. #1
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147

    Which smart pointer to use?

    I'm trying to learn how to work with Boost and I'm a little confused as to how to handle an API in C using smart pointers.

    In this case, the API I'm using returns a const char*. I want to be able to wrap that into a smart pointer that transfers ownership when it's passed out of a function and loses scope.

    My first thought was to use auto_ptr<T> but it would appear that it's being deprecated from the standard library? I'm a little hesitant to use auto_ptr anyway because it's got its share of problems associated with it but I'm unsure if it is the appropriate smart pointer to use in this case.

    So I figured instead of using auto_ptr Boost would probably offer something more appropriate. I know that the set of _ptr's can't store arrays so that leaves scoped_array and shared_array. I understand that scoped_array is non-transferable and so when a function that creates it returns, it goes out of scope and is destroyed (e.g., I can't pass it out of the function and hope that the program will work correctly if it even compiles).

    shared_array does a reference count -- but does that mean that when the function that creates it returns, that shared_array would decrement its reference and effectively become a transfered object? When I run that function again will it create a completely new shared_array with a new reference count?

    Finally, how can I effectively use shared_array to store a const char*? Or do I have to use a char*? I don't want to use a std::string because that method doesn't seem to work properly (I'm using a filesystem API written in C and some binary files return what appear to be NULL characters despite not having actually reached the end of the file and it seems that std::string truncates itself to the first NULL value it finds breaking the whole system).

    Thanks for taking the time to look over this post!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by leeor_net
    My first thought was to use auto_ptr<T> but it would appear that it's being deprecated from the standard library? I'm a little hesitant to use auto_ptr anyway because it's got its share of problems associated with it but I'm unsure if it is the appropriate smart pointer to use in this case.
    As far as I know, std::auto_ptr is not being deprecated.

    Quote Originally Posted by leeor_net
    I know that the set of _ptr's can't store arrays so that leaves scoped_array and shared_array.
    Yes, if the pointer that you get from that API points to a dynamically allocated array of char, then auto_ptr is wrong to begin with.

    I suspect that the correct solution for you would be to use a std::vector<char> that is initialised using the const char* and presumably the size of the array.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    I never thought to do that but it makes perfect sense to me. I assume I can't simply assign the value:

    Code:
    const char* myCharArray;
    std::vector<char> myArray;
    
    myArray = myCharArray;
    What's an effective method to fill out the vector with char*? How can I then convert the vector back to a C string?

    I ask because after getting the char* buffer from the filesystem, I then pass that buffer into yet another C API (SDL in the case) using its RWOps to read data from a byte buffer.

    I wish I was more familiar with this sort of thing... -_-

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I don't want to use a std::string because that method doesn't seem to work properly (I'm using a filesystem API written in C and some binary files return what appear to be NULL characters despite not having actually reached the end of the file and it seems that std::string truncates itself to the first NULL value it finds breaking the whole system).
    std::string itself has no problem with null characters. It is truncated when you construct it from a C-style string since null-terminator is how the end of string is recognized. There should be constructors and other methods that also take a count (or a range) and don't rely on the null terminator.

    Code:
    #include <string>
    #include <iostream>
    
    int main()
    {
        const char* str = "hello\0world";
        std::string s(str, 11);
        std::cout << s << '\n' << s.size() << '\n';
    }
    (You'd probably use a vector though, when you want to pass a modifiable buffer to functions taking a C-style string by passing the address of the first character. If the API takes const char*, then you can use std::string and just pass c_str().)
    Last edited by anon; 04-13-2009 at 04:30 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Apr 2004
    Location
    Ohio
    Posts
    147
    I didn't realize I could do that. If that's the case than I'll simply construct a std::string using the file length as I have access to that information. It may even simplify my implementation some. Not to mention the utility function c_str() makes things very easy in terms of passing that information on to other API's like SDL.

    Thanks for the tip! I'll give this a shot and see how it works.

    EDIT:
    Wanted to let you know that this worked better than I expected. It also uncovered a problem elsewhere that I had overlooked. Thanks again!
    Last edited by leeor_net; 04-13-2009 at 06:22 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why does C need pointer conversion
    By password636 in forum C Programming
    Replies: 2
    Last Post: 04-10-2009, 07:33 AM
  2. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  3. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  4. Pointer validity check
    By Carlos in forum Windows Programming
    Replies: 6
    Last Post: 12-11-2003, 03:40 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM