Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy argv into new array

I'm getting a segmentation fault for the following code. Can somebody explain why? I would like to be able to copy the contents of argv into a new array, which I called rArray.

#include <iostream>        
using namespace std;

int main( int argc, char **argv)
{
  char **rArray;
  int numRows = argc;
  cout << "You have " << argc << " arguments:" << endl << endl;
  cout << "ARGV ARRAY" << endl;
  for (int i = 0; i < argc; i++)
  { 
    cout << argv[i] << endl;
  }
  cout << endl << endl << "COPIED ARRAY" << endl;
  for(int i; i < numRows; i++)
  {
    for (int j = 0; j < argc; j++)
      {
        rArray[i][j] = argv[i][j];
      }
  }
  for (int i = 0; i < argc; i++)
  {
    cout << "Copied array at index " << i << "is equal to " << rArray[i] << endl;;
  }
  cin.get();
}

The program outputs :

/a.out hello world
You have 3 arguments:

ARGV ARRAY
./a.out
hello
world


COPIED ARRAY
Segmentation fault: 11

Why am I getting this error? How do I fix it?

EDIT: I got a fix, changing the char **rArray to string rArray, and dynamically allocating the size from there.

like image 799
ellman121 Avatar asked Feb 12 '14 18:02

ellman121


3 Answers

Others pointed out various issues with your code; if you actually want to copy argv, use a std::vector of std::string objects:

#include <string>
#include <vector>

int main( int argc, char **argv ) {
    std::vector<std::string> args( argv, argv + argc );
}
like image 56
Frerich Raabe Avatar answered Nov 20 '22 17:11

Frerich Raabe


You need to allocate memory for rArray and also need to initialise the outer loop counter i.

Since the contents of argv are constant strings, you could just copy pointers to them

rArray = new char*[argc+1];
for(int i=0; i <= argc; i++) {
    rArray[i] = argv[i];
}
// use rArray
delete [] rArray;

Note that argv[argc] is guaranteed to be NULL. I've updated the loop to copy this as well (hence the unusual looking i<=argc exit condition)

If you really want to copy the content of the strings (as minitech suggests), the code becomes a bit more complicated:

rArray = new char*[argc+1];
for(int i=0; i < argc; i++) {
    int len = strlen(argv[i]) + 1;
    rArray[i] = new char[len];
    strcpy(rArray[i], argv[i]);
}
rArray[argc] = NULL;
// use rArray
for(int i=0; i < argc; i++) {
    delete [] rArray[i];
}
delete [] rArray;
like image 33
simonc Avatar answered Nov 20 '22 15:11

simonc


One thing is that you are not initializing i

for(int i; i < numRows; i++)
        ^-- !

second thing is that rArray is not allocated

I suggest to use std::vector<std::string>, and copy all you arguments to vector, you will not need to worry about allocations/freeing memory.

like image 3
marcinj Avatar answered Nov 20 '22 15:11

marcinj