Я недавно столкнулся с очень подлой ошибкой, в которой я забываю разыменовывать указатель на строку (массив символов) и таким образом иногда перезаписывал один байт на стеке.
Плохо:
char ** str;
(*str) = malloc(10);
...
str[2] = 'a'; //overwrites 3 bytes from the location in which str is stored
Исправленный:
char ** str;
(*str) = malloc(10);
...
(*str)[2] = 'a';
GCC не произвел предупреждений, и эта ошибка приведет к очень серьезному и реальному использованию как значение, которое это иногда перезаписывало, содержал размер буфера. Я только поймал эту ошибку, потому что я получил luckly, и это вызвало очевидный отказ.
Кроме доверия удаче и/или никогда использования C для чего-нибудь, какие защитные методы кодирования и приемы Вы используете для ловли странных ошибок C?
Я думаю о перемещении в MemCheck valgrind, кто-либо использовал его? Я подозреваю, что это не поймало бы эту ошибку. Кто-либо знает?
Есть ли инструменты для ловли разыменования указателя или арифметических ошибок? Это даже возможно?
Вот требуемый пример кода, он не бросает предупреждений.
#include
void test(unsigned char** byteArray){
(*byteArray) = (unsigned char*)malloc(5);
byteArray[4] = 0x0;
}
int main(void){
unsigned char* str;
test(&str);
return 0;
}
Компиляция не вызывает ошибок:
gcc -Wall testBug.c -o testBug
Выполнение вызывает отказ seg:
./testBug
Segmentation fault
Это - версия GCC, который я использую:
gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.1-4ubuntu9' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
Мой лучший защитный указатель стратегии: сильно избегайте использования более одного уровня косвения. Дереференцирование указателя-указателя на назначение памяти ему в порядке. Но чтобы затем использовать назначенную память в качестве массива просит неприятностей, которые вы получили. Я бы сделал это что-то вроде:
char **outStr;
*outStr = malloc(10);
char *str = *outStr;
str[2] = 10;
ОК, на самом деле это просто стратегия хранения мою здоюзность, которая также имеет оборонительную ценность. Указатели довольно легко понять, когда в некотором раз превышается не более одного уровня косвения, и легче сделать работу кода прямо, когда вы хорошо понимаете.
Что ж, первоначальная причина, по которой я выбрал OpenID, заключалась в том, чтобы кто-то другой мог обработать как можно больше реализации и безопасности аутентификации для меня.
После просмотра OpenID появляется что-то называемое «немедленным запросом» ( http://openid.net/specs/openid-authentication-2_0.html#anchor28 ).
При запросе аутентификации Доверяющая сторона МОЖЕТ запросить, чтобы ОП не взаимодействовала с конечным пользователем. В этом случае ОП ДОЛЖЕН немедленно ответить либо утверждением, что аутентификация успешна, либо ответом, указывающим, что запрос не может быть выполнен без дальнейшего взаимодействия с пользователем.
Из-за этого я думаю, что я мог бы просто сохранить URL-адрес openID пользователя в файле cookie и использовать немедленный запрос, чтобы увидеть, аутентифицирован ли пользователь или нет. Таким образом, мне не нужно ничего делать с моей базой данных, или реализовать любую логику для предотвращения захвата сеанса долгоживущего файла cookie.
Этот метод выполнения, по-видимому, является способом, который OpenID предлагает сделать с помощью документа Best Practices .
-121--2308818-В целом сайт становится проще переваривать для остальной части Интернета. Данные можно использовать повторно, объединять, создавать перекрестные ссылки и сохранять.
Простым примером было бы иметь в любом месте на сайт широту и долготу (гео). С помощью микроформатов любой, кто ищет эту широту и долготу, может быть легко связан со своим веб-сайтом, увеличивая трафик, узнавая об этом человеке/компании и позволяя пользователям легко сохранять эту информацию. (Хотя я сталкивался с этим мало лично, это скорее «будущее» вещей, чем настоящее. Но всегда хорошо быть в курсе событий).
Вторым примером может быть визитная карточка (hCard), где браузер может легко сохранить и перенести ее в адресную книгу, так что только один визит на сайт и посетитель имеет информацию, сохраненную локально. Особенно полезно, если они получают хиты с мобильного телефона.
-121--4903969-Я использую Valgrind, это спасатель жизни!
valgrind --tool=memcheck -v ./yourapp
И MemCheck обнаружит недопустимую запись с «str [2] =» a «;».
Нет встроенного класса, подобного HashSet < T >
, за исключением этого одиночного поведения.
Если вам это нужно, я бы порекомендовал прокрутить свой собственный. Однако подкласс HashSet < T >
не рекомендуется. Ни один из методов (например, Add
, который явно требуется изменить) не является виртуальным, поскольку он не был разработан с учетом подкласса. Это приведет к странному использованию, так как вы скрываете унаследованные методы.
Просто инкапсулируйте HashSet < T >
и откройте необходимые членов. Единственный реальный «код», который нужно добавить, это единственная проверка NULL для метода Add - в противном случае просто передайте все методы инкапсулированному экземпляру.
Если вы хотите, чтобы это был общий класс, вам нужно будет добавить дополнительное ограничение только для работы с классами, так как вы хотите иметь проверку null:
public class ValueSet<T> : ICollection<T>, IEnumerable<T>, ICollection
where T : class
{
private HashSet<T> hashSet = new HashSet<T>();
// ... Implement all members as needed...
-121--2396249- Я думаю о семействе продуктов, которые включают Ms Access, Excel, Clarion для DOS и т.д. Где можно создавать приложения с 0 исходным кодом и без программистов. Не то чтобы они способны выполнять операции AI качества , но они могут делать очень удобные приложения.
-121--4180350-GCC должен дать вам
warning: assignment makes pointer from integer without a cast
Нет?
Пожалуйста, используйте VALGRIND. Это одна из лучших инструментов проверки памяти, которые я наткнулся. Это, безусловно, обнаружит вашу ошибку.
Помимо обнаружения ошибок памяти, VALGRIND также помогает обнаруживать утечки памяти, в использовании блоков памяти и т. Д.
Даже IBM Rational Purify поможет вам при обнаружении таких ошибок. Хотя мой личный любимый валгринд.
Мое предложение - не инструмент, а лучшая практика: тестирование. Такие ошибки обычно очень легко найти при тщательном тестировании кода, начиная с самого нижнего уровня модульного тестирования.
Код, который вы показываете, никогда не даст правильного результата - это не то, что иногда работает, а иногда нет. Модульный тест для этого фрагмента кода может сэкономить часы на отладке позже, когда он будет интегрирован с другими частями системы.
Модульное тестирование может быть дополнено проверкой покрытия: либо с помощью автоматического инструмента, либо просто вручную сканировать код и писать тесты, нацеленные на каждую часть - на самом деле это отличный способ перечитать ваш код (еще один инструмент отладки) и на удивление эффективен.