2014-09-07 1 views
0

Попытка выяснить причины механики c строк.C++ cin to c string динамическое размещение

char** text; 
text = new char*[5]; 
for(int i = 0; int < 5; int++) { 
    cout << endl << "Enter a phrase: "; 
    cin >> text[i]; 
    cout << text[i]; 
} 

Я не совсем уверен, почему это работает в течение первых 2-х итераций, даже успешно отображая их, но получает ошибку Segfault на 3-й итерации.

+1

Поскольку вы выделили массив указателей, но эти указатели не указывают на ничего конкретно. 'cin' не будет выполнять дополнительные ассигнования для вас. –

+1

Это «работает», потому что вы переписываете случайную память, которая, случается, принадлежит вашей программе на первых двух итерациях, но не на третьем. – Cameron

ответ

4

Вы используете неинициализированную память. Вы испытываете неопределенное поведение.

Линия

text = new char*[5]; 

выделенной память на пять указателей, но эти указатели не были инициализированы, чтобы указать на что-либо действительное. Прежде чем вы сможете использовать text[i] для чтения данных, вам необходимо выделить для него память.

for(int i = 0; int < 5; int++) { 
    cout << endl << "Enter a phrase: "; 
    text[i] = new char[SOME_SIZE_LARGE_ENOUGH_FOR_YOUR_NEED]; 
    cin >> text[i]; 
    cout << text[i]; 
} 

Тогда он должен работать.

1

Вы выделили память для 5 указателей, но вы не выделяете ничего, на что указывают эти пять указателей. Предполагая, что вы используете современный 64-разрядный процессор с 8-байтовыми указателями, ваш оператор new выделяет ровно 40 байт, пять восьмибайтовых указателей. Их исходное содержимое - это случайная, неинициализированная память, и когда вы пишете им, они интерпретируются как указатели на случайные адреса памяти, которые в конечном итоге повреждены тем, что вы читали с std::cin. Сначала вам повезло, и первые две итерации где-то нацарапали какую-то память, но ваша программа продолжала хромать, но вы выиграли в лотерею с третьей попытки; попадание случайного адреса, который не существует, и segfault.

Хотя вы можете переписать это для правильного распределения, если вы действительно пытаетесь написать C++, а не C, здесь нет причин ничего выделять. Почему вы хотите иметь дело с распределением памяти, когда C++ с радостью сделает это за вас?

std::vector<std::string> text; 

for(int i = 0; int < 5; int++) 
{ 
    std::cout << std::endl << "Enter a phrase: "; 

    std::string s; 

    if (std::getline(std::cin, s).eof()) 
    break; 

    text.push_back(s); 

    std::cout << s << std::endl; 
}