2014-02-12 3 views
3

Я получаю ошибку сегментации для следующего кода. Может кто-нибудь объяснить, почему? Я хотел бы иметь возможность скопировать содержимое argv в новый массив, который я назвал rArray.Копирование argv в новый массив

#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(); 
} 

Программа выводит:

/a.out hello world 
You have 3 arguments: 

ARGV ARRAY 
./a.out 
hello 
world 


COPIED ARRAY 
Segmentation fault: 11 

Почему я получаю эту ошибку? Как это исправить?

EDIT: У меня есть исправление, меняя char **rArray на string rArray и динамически выделяя размер оттуда.

+1

'символ ** rArray' не выделяет память для вас, и' J Ryan

+0

@minitech Технически 'char ** rArray;' выделяет пространство стека (достаточно удерживать указатель). –

+0

@FrerichRaabe: Да, я вынул «вообще» из-за этого = P – Ryan

ответ

9

Вам необходимо выделить память для rArray, а также необходимо инициализировать счетчик внешнего контура i.

Поскольку содержимое argv постоянные строки, вы можете просто скопировать указатели на них

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

Обратите внимание, что argv[argc] гарантированно будет NULL. Я обновил цикл, чтобы скопировать это, а также (отсюда и необычное состояние ищет i<=argc выхода)

Если вы действительно хотите, чтобы скопировать содержимое строк (как Minitech предполагает), код становится немного сложнее:

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; 
+2

Это не копирует сами строки, не так ли? Я думаю, что это могло быть намерением искателя. В любом случае, это '<', а не '<=', правильно? – Ryan

+0

@minitech Я заметил, что строки не копируются (и не нуждаются). '<=' преднамеренно - я отредактирую, чтобы объяснить, почему – simonc

+2

Да, 'argv [argc]' гарантированно будет 'NULL', но' rArray [argc] 'также гарантированно выходит за рамки ... – Ryan

3

Одно дела, что вы не инициализируетесь i

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

второй вещь, что rArray не выделяется

Я предлагаю использовать std::vector<std::string>, и скопировать все, что вам аргументы вектора, вам не нужны будет беспокоиться о распределении/освобождении памяти.

8

Другие отметили различные проблемы с вашим кодом; если вы на самом деле хотите скопировать argv, используйте std::vector из std::string объектов:

#include <string> 
#include <vector> 

int main(int argc, char **argv) { 
    std::vector<std::string> args(argv, argv + argc); 
} 
+3

+1 для прекрасного решения. –

+1

+1 - гораздо лучшее решение. Если вы добавите примечание о проблемах, связанных с возникновением сбоев, с текущим кодом, я удалю свой ответ. – simonc

Смежные вопросы