1

I have this code:

v8::Handle<v8::Value> StartMethod(const v8::Arguments &args) {
    v8::HandleScope scope; // node_isolate
    int length = args.Length();
    std::vector<std::unique_ptr<char[]>> argv;
    for(int i=0;i<length;++i) {
        if(args[i]->IsString()) {
            v8::String::Utf8Value str(args[i]);
            const int strLen = ToCStringLen(str);
            if(strLen) {
                std::unique_ptr<char []> data(new char[strLen+1]);
                strcpy_s(data.get(), strLen+1, ToCString(str));
                argv.push_back(std::move(data));
            }
        }
    }
    return scope.Close(v8::Int32::New(MainMethod(argv.size(), &(argv[0]._Myptr))));
}

I am using std::move and it is working fine. When i do not use std::move it gives me compiler errors because of unavailability of assignment function.

But Does it guarantees that when vector changes its location, may be because of some internal re sizing and move objects around, nothing bad would happen ?

Ashish Negi
  • 5,193
  • 8
  • 51
  • 95
  • 3
    Am I the only one that noticed the `&(argv[0]._Myptr)` in the last line of this? *Accessing* that pointer through this mechanism is bad enough, I don't even want to *guess* why you're passing the address of it to... something. You would be hard-pressed to find something *less* portable or standard. – WhozCraig Sep 20 '13 at 07:47
  • @WhozCraig I actually wanted `char **` at that location. Can you suggest a better method there. – Ashish Negi Sep 20 '13 at 09:36
  • Yes. `char *tmp = data.get();`, and use `&tmp` I assume this is a `strtol`-type function, and if so, and it returns termination info in the resulting pointer-to-pointer (i.e. it modified the pointer) the behavior is beyond undefined. Even *accessing* that member is implementaiton-specific, Use a temp ptr anyway. What you're doing now with `&(argv[0]._Myptr)` is *dreadful*. – WhozCraig Sep 20 '13 at 14:16

2 Answers2

2

vector<T>::push_back gives the strong exception safety guarantee for move-only types if and only if the move construtor of T does not throw.

In your case T is a unique_ptr for array objects, whose move constructor is declared noexcept (§20.7.1.3), so you are indeed fine here: If the internal resizing of the vector throws a bad_alloc, the vector will remain unchanged and usable.

Community
  • 1
  • 1
ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
1

I am not sure if I got your question right, but under the assumption that std::vector doesn't have any unexpected behaviour, yes, it is garantueed. By executing std::move() you transfer the control over the underlaying pointer to the std::unique_ptr in the std::vector. From this point on it should behave like a std::vector<char*>

Theolodis
  • 4,977
  • 3
  • 34
  • 53
  • Would it still retain properties of unique_ptr like deleting after going out of scope ? – Ashish Negi Sep 20 '13 at 07:28
  • Yes (in the sense that your allocated data is deleted when the `vector argv` goes out of scope - and in the sense that an individual piece of data is deleted when its `unique_ptr` is erased from the vector). – us2012 Sep 20 '13 at 07:46
  • of course, executing `std::move()` transfers the control of the underlaying object to the `std::unique_ptr` in the `std::vector>`, what that means is, that it is like if the old `std::unique_ptr` had never existed. – Theolodis Sep 20 '13 at 07:47