2011-09-26 4 views
4

Я был довольно запутан во время программирования раньше, но этот берет торт. В основном я устанавливаю значение в один цикл for, и в следующей итерации он изменяется на значение следующего.Изменения переменной стоимости сами по себе

for (int i = 0; i < 2; ++i) 
{ 
    for (int j = 0; j < numWords[i]; ++j) //numWords [0] = 9, numWords [1] = 7 
    { 
     stb[i][j].word = const_cast<char*>(is (j + 1,1).c_str()); //is(int,length[opt]) converts int to string, c_str() returns const char *, but I need char * 
     cout << is(j+1,1) << ' ' << stb[i][j].word << '\n'; 
    } 
} 

for (int i = 0; i < 2; ++i) 
{ 
    for (int j = 0; j < numWords [i]; ++j) 
    { 
     cout << stb[i][j].word << ' '; 
    } 
    cout << '\n'; 
} 

Выход:

 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
8 8 
9 9 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
7 7 7 7 7 7 7 7 7 
7 7 7 7 7 7 7 

Моя единственная догадка сейчас что-то с сопзЬ, но это не имеет смысла, поэтому она будет держать изменения всех предыдущих элементов массива ...

+3

Вы еще должны показать нам 'is()'. –

+0

Ну, я просто нашел причину. Прежде всего, is() отлично работает, но я только что узнал, что, поскольку строки не должны хранить каждый символ в последовательных ячейках памяти, как только строка, которую вы передаете cstr(), изменяется, так и char * вы получаете от него. Go figure Я трачу на это много времени:/ – chris

+1

НЕ используйте 'const_cast'. Когда-либо. (К тому времени, когда у вас будет достаточно опыта на C++, чтобы знать, когда это будет безопасно, вы узнаете лучшие методы.) –

ответ

3

Это довольно просто. Ваша программа имеет неопределенное поведение (если мои предположения о is() верны).

is(int, length) возвращает std::string по стоимости. Вы получаете указатель на некоторую внутреннюю структуру в этом string с помощью c_str(). Затем эта строка разрушается в конце полного выражения . Это разрушение аннулирует указатели, полученные вами от c_str().

Это означает, что вы заполняете массив указателями на недопустимую память. Затем вы читаете эти указатели, чтобы распечатать содержимое массива. Чтение из недопустимой памяти приводит к неопределенному поведению.

Возможное объяснение наблюдаемого поведения заключается в следующем:

Каждый string что is возвращает повторно ту же память. В первом цикле вы читаете из памяти, прежде чем он будет перезаписан другим вызовом is, и вы получите правильное значение. Во втором цикле вы читаете из памяти после того, как она была перезаписана, и вы получите окончательное значение в массиве.

+0

Это имеет смысл. Теперь моя проблема в том, что ничто, что я пытаюсь, не будет работать так, как оно предназначено. Мне нужно слово char *. – chris

+1

@chris - создайте отдельный 'std :: vector' или массив, которому принадлежат строки, а затем получите' char * 'из строк, находящихся в этом массиве. – Mankarse