1

I write the following c++ code :

int main() {
     char *argv[4];
     cin >> argv[0] >> argv[1] >> argv[2] >> argv[3];
     cout << argv[0] << argv[1] << argv[2] << argv[3] << endl;
     return 0;
 }

This gives me a segmentation fault 11. But If I initialise the array with 4 string values instead of taking user input and then print, it works fine.

Also, If I try the following :

int main() {
    char *argv[4] = {"bg","demo","running","2"};
    cout << argv[0] << argv[1] << argv[2] << argv[3] << endl;
    cin >> argv[0] >> argv[1] >> argv[2] >> argv[3];
    cout << argv[0] << argv[1] << argv[2] << argv[3] << endl;

    return 0;
}

I get bus error 10. Kindly tell me what I'm doing wrong. I don't see any illegal memory accesses.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
Sim
  • 27
  • 4
  • Literal strings aren't writable. You're trying to overwrite them when you do `cin >> argv[0]` – Barmar Feb 13 '17 at 08:35
  • 1
    Have you consider using `std::string argv[4]` ? Make life easier. – Chen OT Feb 13 '17 at 08:37
  • And if the user enters words longer than those initial values, you'll write out of bounds. Why aren't you using `std::string` instead of `char*`? – Barmar Feb 13 '17 at 08:37
  • @Barmar and Chen OT I have to pass the array to execvp later, and that function needs a char* array – Sim Feb 13 '17 at 08:40
  • @Sim You can use `.c_str()` to get a `char*` array from `std::string` – Barmar Feb 13 '17 at 08:41
  • @Barmar and anyway this doesn't explain the first code's erroe – Sim Feb 13 '17 at 08:42
  • 1
    @Sim I thought you understood the first code's error, and just wanted an explanation for the second one. The first code's error is that you're trying to indirect through uninitialized pointers. – Barmar Feb 13 '17 at 08:43
  • " don't see any illegal memory accesses" - after `char *argv[4]; cin>>argv[0]`, where in memory do you think the characters are stored? – M.M Feb 13 '17 at 08:47
  • Also, the second code is an error since 2011 (string literal can no longer be implicitly converted to non-const `char *`) – M.M Feb 13 '17 at 08:48
  • @M.M Thanks a lot – Sim Feb 13 '17 at 09:28

3 Answers3

2

The argv[i] of char* argv[4]; is only a pointer to nowhere.

You need to prepare/allocate the space for input string writing, and let the argv[i] point to.

Methods like the following:

Fixed length

Space is allocated at stack. Fast but the length must be decided at compile time.

#define STR_SIZE 260
char argv[4][STR_SIZE];

Dynamic length

Space is in the heap. Memory allocation on heap operation is slower, but its length can be adjusted at runtime.

char* argv[4];
for(int i = 0; i < 4; i++)
    argv[i] = new char[can_be_decided_at_runtime];

C++ way

Let the std::string handle the allocation for you.

std::string argv[4];
// Then use argv[i].c_str(); to get inner const char* pointer.
Chen OT
  • 3,486
  • 2
  • 24
  • 46
0

You should probably use std::string instead of char*, since you are writing C++ and not C; you can use the c_str() method if you need to convert from std::string to char* for C functions.

In the first case you have to reserve memory for your strings like this:

int main()
{
    char *argv[4];
    //reserve 10 bytes for each char*
    argv[0] = new char[10];
    argv[1] = new char[10];
    argv[2] = new char[10];
    argv[3] = new char[10];
    cin>>argv[0]>>argv[1]>>argv[2]>>argv[3];
    cout<<argv[0]<<argv[1]<<argv[2]<<argv[3]<<endl;
    //free each char* to prevent memory leaks
    delete[] argv[0];
    delete[] argv[1];
    delete[] argv[2];
    delete[] argv[3];

    return 0;
}

To write the same code using std::string, you would have something like the following:

int main()
{
    std::string argv[4];
    cin>>argv[0]>>argv[1]>>argv[2]>>argv[3];
    cout<<argv[0]<<argv[1]<<argv[2]<<argv[3]<<endl;

    return 0;
}
theVoid
  • 743
  • 4
  • 14
0

EDITED: Ty Barmar

char *argv[4];

This argv char currently points to addresses that are not from the scope of your application.

You have to initialize every single argv to a given length

for (int i = 0; i < 4; i++)
    argv[i] = new char[2];

But keep in mind that you really have to be sure about the lenght of every argument that you will write into the console.

new char[2]

is only sufficient if you type

a b c d

into the console!

Otherwise you will have to write a function that processes the indefinite input length. Another way is to use std::string's .c_str() method, that returns const char*

Community
  • 1
  • 1
Vect0rZ
  • 401
  • 2
  • 6