3

I read that using raw pointers in C++ is bad. Instead we should use auto_ptr. In the below code I am populating a vector in foo() that is created in the main(). Am I doing it right or is there a better way to do without using explicit pointers.

#include <iostream>
#include <vector>
#include <string>

using namespace std;

void foo(vector<string> *v){

    (*v).push_back(" hru");
}

int main(){
    vector<string> v;
    v.push_back("hi");
    foo(&v);
    for(int i=0;i<v.size(); i++){
        cout << v[i];
    }

}
FourOfAKind
  • 2,298
  • 5
  • 31
  • 34
  • 1
    `auto_ptr` is usually not what you want. – Oliver Charlesworth Jan 12 '12 at 16:51
  • Who said raw pointers is bad ? It is not bad till you understand the mechanics of pointers memory allocation and deallocation and what you should be doing. This is some more smart pointers used in C++(http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/smart_ptr.htm). Never mix STL containers and auto_ptr. – DumbCoder Jan 12 '12 at 16:52
  • @DumbCoder I think you mean "it is _only_ bad till you understand..." – Seth Carnegie Jan 12 '12 at 16:54
  • You should just about never use `auto_ptr`, it's deprecated in `C++11`. Use `shared_ptr` or `unique_ptr` instead (found in `std` for C++11, `std::tr1` before for `shared_ptr` and of course always in `boost`). Furthermore it's not using raw pointers which is bad, but using manual memory management (which doesn't occur in your code) @SethCarnegie: I would think it should be "it's bad till you understand it and afterwards". – Grizzly Jan 12 '12 at 16:56
  • 2
    @OliCharlesworth Actually, unless you have the newer `unique_ptr`, `auto_ptr` is the most useful of the commonly available smart pointers. (Although in his case, he should be using references, and not pointers.) – James Kanze Jan 12 '12 at 16:57
  • 1
    Don't use raw pointers for managing objects' lifetimes, or for referring to objects whose lifetime you don't know. In this case, `v` is automatically managed, and guaranteed to remain valid throughout the pointer's lifetime, so there's no problem with using a pointer. Whether to replace it with a reference is a matter of personal taste. – Mike Seymour Jan 12 '12 at 16:59
  • @Grizzly pointers aren't bad if you know how to use them, but smart pointers are better for some situations. – Seth Carnegie Jan 12 '12 at 17:03
  • 2
    The reason raw pointers are "bad" is because raw pointers lack intrinsic *semantics*: the pointer itself never knows who is responsible for what it's pointing at, or whether it's pointing at something useful at all. References don't have this problem since it's clear that they only *refer* to something without being responsible for it, and smart pointers have well defined ownership semantics. – Kerrek SB Jan 12 '12 at 17:06
  • @JamesKanze: Depending on your definition of "commonly available", it's the only one. Where others are available (namely `shared_ptr`), I'd suggest that as the default _for newbies_. – sbi Jan 12 '12 at 17:06
  • @Grizzly: From your comment what I understand is when the function foo() gets called memory for vector is created on the heap? – FourOfAKind Jan 12 '12 at 17:09
  • @Grizzly: Or it just creates variable v on the foo's stack and it points the vector on the main's stack? – FourOfAKind Jan 12 '12 at 17:13
  • @Lamia: the memory for the vector gets allocated on the stack when it's defined in `main`. Internally `vector` uses heap allocated memory, but that doesn't need to concern you. So your second comment is basically correct @Seth carnegie: As I said it's not raw pointers which are bad, but manual memory management (which shouldn't be used without good reason (though lack of access to low overhead smartptrs might count)). – Grizzly Jan 12 '12 at 17:16
  • @KerrekSB That's just wrong. Raw pointers have very definite semantics, strictly defined by the standard. They're still the most common type of pointers in most code---smart pointers are generally reserved for special cases. – James Kanze Jan 12 '12 at 17:36
  • @sbi Even when `shard_ptr` is available, it's far less useful (especially for beginners) than `auto_ptr`. Use raw pointers most of the time. After that, `unique_ptr` is the most useful, but it isn't always available---`auto_ptr` comes fairly close, and is universally available. `shared_ptr` is really only for a few, very special cases. – James Kanze Jan 12 '12 at 17:39
  • @JamesKanze: Well, I guess we'll just have to agree to disagree then. You're swimming against the tide here. I suppose most of us have had terrible times with other people's code that manually managed resources. I have taught C++ to students who had previous exposure to Java. I know resources can be managed manually, but I also know that beginners shouldn't attempt to do that. – sbi Jan 12 '12 at 19:47
  • 1
    @sbi The problem with people coming from Java is that they dynamically allocate things they shouldn't; the answer to that isn't smart pointers, but to not allocate dynamically. For the things you should allocate dynamically in C++, `shared_ptr` often creates more problems than it solves. – James Kanze Jan 12 '12 at 20:03
  • @JamesKanze: That wasn't the problem my students had. – sbi Jan 12 '12 at 21:03
  • @sbi Student applications are very different from real applications. – James Kanze Jan 13 '12 at 13:11
  • @JamesKanze: Which is exactly why I said I wouldn't suggest this here. If it such is asked here by a 100rep user, it's most likely a student. – sbi Jan 13 '12 at 13:13

3 Answers3

4

C++ uses references for what you are trying to do:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

void foo(vector<string>& v){
    v.push_back(" hru");
}

int main(){
    vector<string> v;
    v.push_back("hi");
    foo(v);
    for(int i=0;i<v.size(); i++){
        cout << v[i];
    }
}

References and pointers are similar, with one very important distinction: there is no such thing as a null reference (Constructing one is Undefined Behavior in C++ you can construct one, but doing so is considered a hack).

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    In reference to your "you can construct one": C++ has no such thing as a null reference and creating one is undefined behaviour. – Tony The Lion Jan 12 '12 at 16:58
  • @TonyTheLion That's more or less what I said, except I used a popular synonym for "undefined behaviour" :) – Sergey Kalinichenko Jan 12 '12 at 17:00
  • oh, I see. So I guess "a hack" is another way of saying UB. TIL – Tony The Lion Jan 12 '12 at 17:02
  • 1
    I agree with @TonyTheLion. You might *accidentally* get a null reference, but trying to construct one is completely idiotic because of the undefined behavior; I wouldn't grace it with the term "hack". See http://stackoverflow.com/a/57656/5987 – Mark Ransom Jan 12 '12 at 17:07
  • @MarkRansom I guess you are right: "hack" is not universally regarded as a pejorative, so I edited the answer. – Sergey Kalinichenko Jan 12 '12 at 17:14
3

In C++ you can avoid the pointer and use a pass-by-reference:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

void foo(vector<string>& v){

    v.push_back(" hru");
}

int main(){
    vector<string> v;
    v.push_back("hi");
    foo(v);
    for(int i=0;i<v.size(); i++){
        cout << v[i];
    }    
}
Tudor
  • 61,523
  • 12
  • 102
  • 142
0

You can begin to think about using auto_ptr when you deal with objects created on heap (e.g. a class instance created by "new"). Your vector holds its elements by value, std::string elements it is. So you don't need to consider auto_ptr here at all. If your vector would hold instances created on heap then you could use something like this:

std::vector< auto_ptr< MyType > > vec;

auto_ptr< MyType > a( new MyType() );

vec.push_back( a );

and then when your vector elements get erased by e.g. your vec leaving its scope then instance 'a' will get deleted automatically.

With other words, auto_ptr is a kind of garbage collector which does a kind of automatic object deletion for you. See here for more information about auto_ptr http://www.cplusplus.com/reference/std/memory/auto_ptr

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
boto
  • 455
  • 2
  • 13
  • std::auto_ptr in a std::vector is never a good idea. If you need this type of functionality you should use a boost::ptr_vector instead. – mocj Jan 12 '12 at 18:00
  • 1
    @boto: Thanks for the answer. I think it is a bad idea to do that. I found some question related to this http://stackoverflow.com/questions/4577838/smart-pointers-in-container-like-stdvector – FourOfAKind Jan 12 '12 at 18:07
  • Right, I would never use auto_ptr as a smart pointer, because it simply is not a smart pointer. But they do a good job for temporary holding objects in a limited scope and not worrying about deleting them. – boto Jan 13 '12 at 13:58