2017-02-13 2 views
1

Я пишу следующий C++ код:ошибка шины 10 - символ * массив

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; 
} 

Это дает мне ошибку сегментации 11. Но если я инициализирует массив с 4 string значений вместо приема пользовательского ввода, а затем распечатать , он отлично работает.

Кроме того, если я попробовать следующее:

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; 
} 

Я получаю автобус ошибка 10. Пожалуйста, скажите мне, что я делаю неправильно. Я не вижу незаконного доступа к памяти.

+0

Литеральные строки не доступны для записи. Вы пытаетесь перезаписать их, когда вы делаете 'cin >> argv [0]' – Barmar

+1

Считаете ли вы использование 'std :: string argv [4]'? Делать жизнь легче. –

+0

И если пользователь вводит слова дольше, чем эти начальные значения, вы выходите из пределов. Почему вы не используете 'std :: string' вместо' char * '? – Barmar

ответ

0

Возможно, вы используете std::string вместо char*, так как вы пишете C++, а не C; вы можете использовать метод c_str(), если вам необходимо конвертировать из std::string в char* для функций C.

В первом случае необходимо резервировать память для ваших строк, как это:

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; 
} 

Чтобы написать тот же код, используя std::string, вы бы что-то вроде следующего:

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; 
} 
+1

Спасибо! Works :) – Sim

0

EDITED : Ty Barmar

char *argv[4]; 

Этот атрибут argv в настоящее время ts к адресам, которые не относятся к сфере применения вашего приложения.

Вы должны инициализировать каждый ARGV до заданной длины

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

Но имейте в виду, что вы действительно должны быть уверены в длине каждого аргумента, что вы будете писать в консоль.

new char[2] 

только достаточно, если вы наберете

a b c d 

в консоль!

В противном случае вам придется написать функцию, которая обрабатывает неопределенную длину ввода. Другой способ заключается в использовании .c_str() метод STD :: струны, которая возвращает константный символ *

+3

'char [1]' даже не достаточно для 1 символа, вам нужно пространство для нулевого терминатора. – Barmar

2

argv[i] из char* argv[4]; только указатель на пустом месте.

Вам необходимо подготовить/выделить пространство для ввода строки ввода, а также указать argv[i].

методы, такие как следующие:

Фиксированная длина

пространство выделяется в стеке. Быстро, но длина должна быть определена во время компиляции.

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

Динамическая длина

Пространство в куче. Распределение памяти в операции кучи происходит медленнее, но ее длина может быть скорректирована во время выполнения.

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

C++ способ

Пусть std::string обрабатывать распределение для вас.

std::string argv[4]; 
// Then use argv[i].c_str(); to get inner const char* pointer.