Standard for returning character arrays?

Discussion in 'C++' started by Justin Naidl, May 16, 2005.

  1. Justin Naidl

    Justin Naidl Guest

    class Foo
    {
    protected:
    char foo_stuff[16];

    public:
    char* get_foo_stuff();
    }

    Given the above example. What I want to know is the "proper/standard" way
    of returning foo_stuff in an accessor function without giving the user
    access to the data directly. The way I currently have it set up is to creat
    an entirely new char array and strcpy foo_stuff into it and return the
    address of the new array. I don't particularly like that method as it
    requires that the caller manually delete the data that is returned. So, I
    guess at this point I will leave it to the experts.


    Thanks,

    ~Justin
    Justin Naidl, May 16, 2005
    #1
    1. Advertising

  2. Justin Naidl wrote:
    > class Foo
    > {
    > protected:
    > char foo_stuff[16];
    >
    > public:
    > char* get_foo_stuff();
    > }

    ;
    >
    > Given the above example. What I want to know is the "proper/standard" way
    > of returning foo_stuff in an accessor function without giving the user
    > access to the data directly.


    As long as the pointer is still valid after you return it, there is no
    problem with returning 'foo_stuff' directly.

    > The way I currently have it set up is to creat
    > an entirely new char array and strcpy foo_stuff into it and return the
    > address of the new array.


    That's just another way. You charge the user with having to delete the
    array after they are done with it.

    > I don't particularly like that method as it
    > requires that the caller manually delete the data that is returned. So, I
    > guess at this point I will leave it to the experts.


    There is nothing special the expert will tell you except, maybe, to use
    'std::string'. Of course, to be sure an expert would know what the
    meaning of 'foo_stuff' is and how the user is supposed to use the return
    value of 'get_foo_stuff'...

    V
    Victor Bazarov, May 16, 2005
    #2
    1. Advertising

  3. Justin Naidl

    John Carson Guest

    "Justin Naidl" <> wrote in message
    news:jb1ie.5444$
    > class Foo
    > {
    > protected:
    > char foo_stuff[16];
    >
    > public:
    > char* get_foo_stuff();
    > }
    >
    > Given the above example. What I want to know is the
    > "proper/standard" way of returning foo_stuff in an accessor function
    > without giving the user access to the data directly. The way I
    > currently have it set up is to creat an entirely new char array and
    > strcpy foo_stuff into it and return the address of the new array. I
    > don't particularly like that method as it requires that the caller
    > manually delete the data that is returned. So, I guess at this point
    > I will leave it to the experts.


    There is no "proper/standard" way. It depends on what you are trying to
    achieve, which will partly depend on how you see the data being used by the
    caller.

    One approach would be to return a pointer to const char. This gives the
    caller "read only" access to the data. If the user wants their own
    modifiable copy of the data, then the user can make a copy and assume full
    responsibility for managing that copy. Generally speaking, there are less
    problems if whoever allocates the memory has the responsibility for deleting
    it.

    Another possibility would be to define an operator[] to give access to data
    one element at a time. This operator could return a char and no dynamic
    memory allocation would be needed.

    --
    John Carson
    John Carson, May 16, 2005
    #3
  4. Justin Naidl

    Rolf Magnus Guest

    Victor Bazarov wrote:

    > Justin Naidl wrote:
    >> class Foo
    >> {
    >> protected:
    >> char foo_stuff[16];
    >>
    >> public:
    >> char* get_foo_stuff();
    >> }

    > ;
    >>
    >> Given the above example. What I want to know is the "proper/standard"
    >> way of returning foo_stuff in an accessor function without giving the
    >> user access to the data directly.

    >
    > As long as the pointer is still valid after you return it, there is no
    > problem with returning 'foo_stuff' directly.


    There is one problem: The user is now able to modify it, even though it's
    not a public member. The get_foo_stuff() function exposes it, which btw.
    means that this function now serves no purpose at all anymore. Just make
    the member public and you have the same functionality without the need for
    an additional function.

    > > The way I currently have it set up is to creat
    >> an entirely new char array and strcpy foo_stuff into it and return the
    >> address of the new array.

    >
    > That's just another way. You charge the user with having to delete the
    > array after they are done with it.


    Other ways would be to store the pointer internally and delete [] the array
    on use of the next function that modifies the object. I think some
    implementations of std::string do this. Another way is to return some type
    of smart pointer instead of a raw pointer.

    > > I don't particularly like that method as it
    >> requires that the caller manually delete the data that is returned. So,
    >> I guess at this point I will leave it to the experts.

    >
    > There is nothing special the expert will tell you except, maybe, to use
    > 'std::string'. Of course, to be sure an expert would know what the
    > meaning of 'foo_stuff' is and how the user is supposed to use the return
    > value of 'get_foo_stuff'...
    >
    > V
    Rolf Magnus, May 16, 2005
    #4
  5. Rolf Magnus wrote:
    > Victor Bazarov wrote:
    >
    >
    >>Justin Naidl wrote:
    >>
    >>>class Foo
    >>>{
    >>> protected:
    >>> char foo_stuff[16];
    >>>
    >>> public:
    >>> char* get_foo_stuff();
    >>>}

    >>
    >> ;
    >>
    >>>Given the above example. What I want to know is the "proper/standard"
    >>>way of returning foo_stuff in an accessor function without giving the
    >>>user access to the data directly.

    >>
    >>As long as the pointer is still valid after you return it, there is no
    >>problem with returning 'foo_stuff' directly.

    >
    >
    > There is one problem: The user is now able to modify it, even though it's
    > not a public member. The get_foo_stuff() function exposes it, which btw.
    > means that this function now serves no purpose at all anymore. Just make
    > the member public and you have the same functionality without the need for
    > an additional function.


    That's nonsense. The function _always_ serves a purpose. If you need to
    register the fact of accessing the private member, or do anything else for
    that matter, you do it in a function.

    > [...]


    V
    Victor Bazarov, May 16, 2005
    #5
  6. Justin Naidl

    Guest

    Be mindful of semantics when mixing the use of char[] and char*. Since
    this appears to be entirely your code, it's probably a non-issue.
    But I have noticed in production code that very often fixed-length char
    arrays (eg, char[x]) are not null-terminated - which means they aren't
    really strings in the common sense.

    In particular, you cannot perform string operations like strcpy() on a
    non-null-terminated char array (because strcpy works by looking for the
    null-terminator). In this case, I have found that very often the
    simplest way to get a 'real' string out of the non-null-term char array
    is to use std::string's ctor specifying a char* substring:

    class Foo
    {
    protected:
    char foo_stuff[16];

    public:
    std::string get_foo_stuff() const;

    } ;

    std::string
    Foo::get_foo_stuff()
    const
    {
    return std::string(&foo_stuff[0],sizeof(foo_stuff));
    }

    Depending on the application, this solution may or may not be
    appropriate for you.

    Take care,

    John Dibling
    , May 16, 2005
    #6
  7. Rolf Magnus wrote:
    > Victor Bazarov wrote:
    >
    >
    >>Rolf Magnus wrote:
    >>
    >>>Victor Bazarov wrote:
    >>>
    >>>
    >>>
    >>>>Justin Naidl wrote:
    >>>>
    >>>>
    >>>>>class Foo
    >>>>>{
    >>>>> protected:
    >>>>> char foo_stuff[16];
    >>>>>
    >>>>> public:
    >>>>> char* get_foo_stuff();
    >>>>>}
    >>>>
    >>>> ;
    >>>>
    >>>>
    >>>>>Given the above example. What I want to know is the "proper/standard"
    >>>>>way of returning foo_stuff in an accessor function without giving the
    >>>>>user access to the data directly.
    >>>>
    >>>>As long as the pointer is still valid after you return it, there is no
    >>>>problem with returning 'foo_stuff' directly.
    >>>
    >>>
    >>>There is one problem: The user is now able to modify it, even though it's
    >>>not a public member. The get_foo_stuff() function exposes it, which btw.
    >>>means that this function now serves no purpose at all anymore. Just make
    >>>the member public and you have the same functionality without the need
    >>>for an additional function.

    >>
    >>That's nonsense. The function _always_ serves a purpose.

    >
    >
    > No. It directly exposes the member to the outside world (i.e. makes it
    > possible for a user of the class to modify the member without the object
    > having control over it). You can do that in a simpler way by just making
    > the member public.


    "Simpler" doesn't make it better.

    >>If you need to register the fact of accessing the private member,
    >>or do anything else for that matter, you do it in a function.

    >
    >
    > You mean that the object notices the access and can do something in the
    > function? Well, the problem is that it doesn't.
    > It registers that someone takes a pointer to the data, but it doesn't
    > register at all whether that 'someone' uses the pointer to read the data,
    > to write it (maybe several times), to store it for later acces, or to just
    > do nothing at all with it.


    So damn what? The mere fact that somebody requests the pointer is
    important. It is _impossible_ to register *that* without a function.

    Besides, if later you decide to change the implementation and so whatever
    else you might deem necessary, it is _impossible_ without a function, and
    with a function, you just change the implementation and not the interface
    or the layout of the class. Making the data member public will definitely
    be worse. That's my point.

    V
    Victor Bazarov, May 16, 2005
    #7
  8. Justin Naidl

    Rolf Magnus Guest

    Victor Bazarov wrote:

    > Rolf Magnus wrote:
    >> Victor Bazarov wrote:
    >>
    >>
    >>>Justin Naidl wrote:
    >>>
    >>>>class Foo
    >>>>{
    >>>> protected:
    >>>> char foo_stuff[16];
    >>>>
    >>>> public:
    >>>> char* get_foo_stuff();
    >>>>}
    >>>
    >>> ;
    >>>
    >>>>Given the above example. What I want to know is the "proper/standard"
    >>>>way of returning foo_stuff in an accessor function without giving the
    >>>>user access to the data directly.
    >>>
    >>>As long as the pointer is still valid after you return it, there is no
    >>>problem with returning 'foo_stuff' directly.

    >>
    >>
    >> There is one problem: The user is now able to modify it, even though it's
    >> not a public member. The get_foo_stuff() function exposes it, which btw.
    >> means that this function now serves no purpose at all anymore. Just make
    >> the member public and you have the same functionality without the need
    >> for an additional function.

    >
    > That's nonsense. The function _always_ serves a purpose.


    No. It directly exposes the member to the outside world (i.e. makes it
    possible for a user of the class to modify the member without the object
    having control over it). You can do that in a simpler way by just making
    the member public.

    > If you need to register the fact of accessing the private member,
    > or do anything else for that matter, you do it in a function.


    You mean that the object notices the access and can do something in the
    function? Well, the problem is that it doesn't.
    It registers that someone takes a pointer to the data, but it doesn't
    register at all whether that 'someone' uses the pointer to read the data,
    to write it (maybe several times), to store it for later acces, or to just
    do nothing at all with it.
    Rolf Magnus, May 16, 2005
    #8
  9. Rolf Magnus wrote:
    > Victor Bazarov wrote:
    > [...]
    >>Making the data member public will definitely b worse. That's my point.

    >
    >
    > Making the data member private is a good idea, but giving away pointers to
    > it to anyone who wants destroys the advantages of that idea. That's my
    > point.


    Your point is valid, but when choosing whether to make it public or wrap
    that public access in a public member function, the latter is much more
    preferable. Read more about abstraction.

    V
    Victor Bazarov, May 16, 2005
    #9
  10. Justin Naidl

    Rolf Magnus Guest

    Victor Bazarov wrote:

    >> No. It directly exposes the member to the outside world (i.e. makes it
    >> possible for a user of the class to modify the member without the object
    >> having control over it). You can do that in a simpler way by just making
    >> the member public.

    >
    > "Simpler" doesn't make it better.


    If there are two ways of doing the same thing, I'd choose the simpler way.

    >>>If you need to register the fact of accessing the private member,
    >>>or do anything else for that matter, you do it in a function.

    >>
    >>
    >> You mean that the object notices the access and can do something in the
    >> function? Well, the problem is that it doesn't.
    >> It registers that someone takes a pointer to the data, but it doesn't
    >> register at all whether that 'someone' uses the pointer to read the data,
    >> to write it (maybe several times), to store it for later acces, or to
    >> just do nothing at all with it.

    >
    > So damn what? The mere fact that somebody requests the pointer is
    > important.


    It is?

    > It is _impossible_ to register *that* without a function.


    Right. But I don't see any advantage.

    > Besides, if later you decide to change the implementation and so whatever
    > else you might deem necessary, it is _impossible_ without a function, and
    > with a function, you just change the implementation and not the interface
    > or the layout of the class.


    You can't, since the function exposes private data directly to the outside
    world.

    > Making the data member public will definitely b worse. That's my point.


    Making the data member private is a good idea, but giving away pointers to
    it to anyone who wants destroys the advantages of that idea. That's my
    point.
    Rolf Magnus, May 16, 2005
    #10
  11. Justin Naidl

    Justin Naidl Guest

    It doesn't give the user access to the member variable guys.

    "The way I currently have it set up is to creat
    an entirely new char array and strcpy foo_stuff into it and return the
    address of the new array. "

    The wrapper function creates a new string and copys the existing string to
    it. Then returns the address of this newly created string. The private
    data member is still not accessible. The problem was that the newly created
    string must be deleted by whoever uses it and cannot be set up to be cleaned
    nicely in the class itself.

    ~Justin
    Justin Naidl, May 24, 2005
    #11
  12. Justin Naidl wrote:
    >
    > It doesn't give the user access to the member variable guys.
    >
    > "The way I currently have it set up is to creat
    > an entirely new char array and strcpy foo_stuff into it and return the
    > address of the new array. "
    >
    > The wrapper function creates a new string and copys the existing string to
    > it. Then returns the address of this newly created string. The private
    > data member is still not accessible. The problem was that the newly created
    > string must be deleted by whoever uses it and cannot be set up to be cleaned
    > nicely in the class itself.
    >


    The question is:
    Why do you use plain vanilla character arrays and not a full blown string
    class like std::string. Then you wouldn't have all those problems.

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, May 24, 2005
    #12
    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. Alexandra Stehman
    Replies:
    5
    Views:
    30,508
    Chris Smith
    Jun 17, 2004
  2. Jeremy Watts
    Replies:
    3
    Views:
    890
    Jeremy Watts
    May 24, 2005
  3. Replies:
    11
    Views:
    646
    Christos Georgiou
    May 2, 2006
  4. jt
    Replies:
    4
    Views:
    562
    Fred L. Kleinschmidt
    May 16, 2005
  5. Philipp
    Replies:
    21
    Views:
    1,093
    Philipp
    Jan 20, 2009
Loading...

Share This Page