Re: vector<string> to char*[]
* Andrew Wingorodov:
Alf P. Steinbach <alfps@start.no> wrote:
auto_ptr calls delete, whereas you need delete[]. Not that it matters
much in practice for a char array. But formally UB.
When the function returns, the auto_ptr calls delete. As mentioned
Try what I posted earlier, it's safe:
i got it, 10x
but i'm afraid that the vector isn't equiv to the array of poiter to chars
Oh. Well, it is.
may be this is a better way?
//--code--
class constchar
{
private:
const char** v;
public:
constchar (const std::vector<std::string>& arg_);
inline virtual ~constchar () { delete [] v; }
inline operator const char** () const { return v; }
}; //!class constchar
It's generally not a good idea to dive down to the level manual memory
management, if it can be avoided.
Not that the code won't work, but it's unsafe if used in other ways than
the example you give below, and if you then later build on your
experience that the above seemed to work and implement other classes
that way, then Mr. Murphy will most likely visit and apply his Law.
Try instead (also addressing constness issues with execve):
<code>
#include <vector>
#include <string>
int execve(const char *, char *const[], char *const[]) { return -1; }
typedef std::vector<std::string> StringVector;
std::string& zeroTerminated( std::string& s )
{
s += '\0';
s.resize( s.size() - 1 );
return s;
}
class RawPointers
{
private:
std::vector<char*> myPointers;
public:
RawPointers( StringVector& arg )
: myPointers( arg.size() + 1 )
{
for( size_t i = 0; i < arg.size(); ++i )
{
myPointers[i] = &zeroTerminated( arg[i] )[0];
}
}
operator char * const * () { return &myPointers[0]; }
};
void callExecVe(
std::string const& filename,
StringVector args,
StringVector env
)
{
execve( filename.c_str(), RawPointers( args ), RawPointers( env ) );
// If execution gets here, the execve call failed.
// throw whatever;
}
int main( int nArgs, char* args[] )
{
callExecVe(
"blablah",
StringVector( args, args + nArgs ),
StringVector()
);
}
</code>
//
constchar::constchar (const std::vector<std::string>& arg_)
{
v = new const char* [arg_.size()+1];
std::vector<std::string>::const_iterator i = arg_.begin();
size_t j;
for (j^=j; i != arg_.end (); ++i)
Why not write just j=0 (far more readable), and why not declare j right
there, in the innermost scope it can be declared?
And why keep incrementing both an index and and an interator?
The index suffices.
{
v[j++] = (*i).c_str() ;
}
v[j] = NULL;
}
int
main ()
//////.......
vector<string> argv;
vector<string> envp;
...
::execve (..., constchar (argv), constchar (envp));
::spawnve (..., constchar (argv), constchar (envp));
//--code--
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?