(Не) статический объект в цикле - PullRequest
0 голосов
/ 03 сентября 2010

В книге есть пример о статических / нестатических объектах.

char buf[MAX];
long count=0;
int i=0;
while(i++<=MAX)
    if(buf[i]=='\0') {
        buf[i]='*';
        ++count;
    }
assert(count<=i);

Говорят, что иногда код записывает после конца массива buf в счетчик и делает утверждение ошибочным.А затем рассказывает о том, как объявить счет как статическое, и решить проблему (примечание: автор приводит это как пример плохого решения) В любом случае, кроме плохого примера, я не могу понять, как возникает проблема и как она решается как объявлениесчитать как статический.

Ответы [ 5 ]

4 голосов
/ 03 сентября 2010

Это не только плохое решение, это не решение .Вы не можете индексировать границы массива.Если вы это сделаете, у вас возникнет проблема неразрешимая , связанная с достижением правильной программы на C ++.

Что вы можете увидеть в распространенных реализациях C ++, так это то, что иногда count помещается в стек сразу после buf.Таким образом, если вы переиндексируете, а затем записываете, вы можете изменить count, и тогда любое предположение о значении count, основанное исключительно на прямых записях в него, больше не будет корректным, поскольку в него записываетсясверхиндексная операция.

Если вы теперь сделаете ее static переменной, то она будет размещена в каком-то другом разделе программы (обычно .bss для 0-инициализированных и .data для иначе инициализированных данных), переменная countобщие реализации больше не будут размещаться рядом с массивом, и это приведет к другому инциденту: вместо перезаписи count вы можете перезаписать все, что находится рядом с массивом.

3 голосов
/ 03 сентября 2010

Пример рассчитывает на конкретное расположение переменных в памяти, а именно, что count следует сразу после buf. Делая count статическим, он помещается в другую часть памяти, а вместо этого происходит что-то другое. Проблема не исчезла, симптомы просто изменились.

1 голос
/ 03 сентября 2010

Йоханнес ответ правильный.

Однако, почему объявление count как static может сделать его видимым для работы. Когда count объявлен как не-static, он обычно будет жить сразу после buf[] в памяти (в стеке). Однако, когда он объявлен как static, он не будет в стеке и, следовательно, не будет поврежден при записи после конца buf[].

0 голосов
/ 03 сентября 2010

Я хотел бы прочитать книгу, но я представляю, что в ней представлены примеры «Программирование вуду», где вы пробуете случайные вещи, пока они не перестанут ломаться, и называете это успехом.

Как упоминалось в другом месте, все, что вы бы сделали, объявив его статическим, - это счетчик перемещений в другое место, что означало бы, что утверждение может пройти. Для неопытного программиста этого будет достаточно для отправки, и в этот момент у вас есть код переполнения буфера в вашей производственной среде.

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

0 голосов
/ 03 сентября 2010

Согласен, если вы превышаете границы массивов, вы вызываете исключение вне границ.Или в неуправляемых языках, таких как C / C ++, вы можете закончить записывать / читать по следующей партии памяти, из памяти моей строки с нулевым символом в конце, бегущей в память других объектов, было неинтересно.

Мне несколько любопытно, где находится ваш статический объект, вы объявляете их все как переменные, статического объекта в поле зрения нет.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...