Программирование >>  Программный интерфейс приложений 

1 ... 100 101 102 [ 103 ] 104 105 106 ... 264


Ошибка № 1 - работа с не проинициализированными указателями дескрипторов соединения

Во всех примерах, которые продемонстрированы в этой главе, функция mysql init() вызывалась с аргументом NULL . Это разрешает mysql init() создать и инициализировать структуру MYSQL и возвратить указатель на нее. Можно воспользоваться и другим подходом, при котором функции mysql init () передается указатель на уже сушествуюшую структуру MySQL. В этом случае mysql init () инициализирует эту структуру и вернет указатель на нее, не создавая при этом новой структурьг Выбирая второй подход, вы должны отдавать себе отчет в том, что он может вызвать определенные скрытые пробле\шг И здесь они будут затронутьг

Указатель, передаваемый функции mysql init (), должен на что-то указывать. Рассмотрим следующий профаммный код:

main О (

MYSQL *conn;

mysql init (conn);

Проблема заключается в том, что функция mysql init О принимает указатель, но этот указатель не указьшает на что-либо имеющее значение. Переменная conn является локальной переменной, она не проинициали-зирована. Следовательно, она может указывать на что угодно в момент старта модуля main (). Это значит, что функция mysql init () будет указывать на совершенно произвольное место в памяти. Хорошо, если указатель conn будет указывать на область памяти, находящуюся вне адресного просфанства вашей профаммы, вследствие чего система тотчас ее остановит. Таким образом сразу же станет ясно, что в профамме содержится какая-то ошибка. Но если удача от вас отвернулась, указатель conn будет указывать на область данных, которая до поры до времени профаммой не используется, и вы просто ничего не заметите. В таком случае проблема возникнет позже во время выполнения профаммы. В таком случае диагностировать и усфанить такую ошибку будет значительно фуднее.

Вот аналогичная часть ошибочного профаммного кода:

MYSQL * conn;

main {) {

mysql init (conn); mysql real connect (conn, ...) mysql query(conn, SHOW DATABASES );

В этом случае переменная conn является глобальной. Она инициализируется со значением О (т.е. NULL ) до момента старта профаммы. Функция mysql init() принимает аргумент со значением NULL и та-



ким образом инициализирует новый дескриптор соединения. К сожалению, переменная conn все еще имеет значение null , поскольку ей так и не присвоено никакого значения. А так как значение conn уже передано функции интерфейса MySQL С API, которая требует, чтобы дескриптор соединения содержал значение, отличное от null , программа прекратит выполнение из-за ошибки. Для того чтобы исправить обе программы, необходимо убедиться, что переменная conn содержит допустимое значение. Например, можно присвоить ей адрес уже существующей структуры MYSQL:

MYSQL conn struct, *conn = Sconn struct; raysql init (conn);

Однако рекомендуемым (и самым простым) решением будет просто задание явным образом функции mysql init О значения null , вынудив тем самым вьщелить структуру mysql и присвоить переменной conn возвращаемое значение:

MYSQL *conn;

conn = raysql init (NULL);

В любом случае, не забывайте проверять значение, возвращаемое функцией mysql init {), чтобы убедиться, что оно не равно null .

Ошибка № 2 - непроверенный результирующий набор

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

MYSQL RES *res set; MYSQL ROW row;

res set = raysql store result (conn);

while ((row = mysql fetch row (res set)) != NULL)

/* обработка строки */

Очевидно, что в случае ошибочного завершения функции mysql store result О значение переменной res set будет null , и цикл while даже не будет выполнен. Таким образом, можно подытожить: обязательно проверяйте значения, возвращаемые функциями, которые возврашают результирующий набор, чтобы было с чем работать.

Ошибка № 3 - ошибка при выявлении столбцов, имеющих значение null

Не забывайте проверять значения столбцов в массиве mysqlrow, возвращаемые функцией mysql f etch row (). Они не должны быть



NULL . Вот программный код, который сбоит на некоторых машинах, когда значение row [i] равно NULL :

for (1 =0; 1 < mysql num fields (res set); {

if (1 > 0)

fputc {\t, stdout); printf ( %s , row[i]);

fputc (\n, stdout);

Самое плохое в данном случае - то, что операторы prmtf () в некоторых версиях прощают эту ошибку и печатают (null) для указателей, имеющих значение NULL . Это позволяет просто уйти от решения проблемьг Если передать эту программу другу, имеющему более строгий оператор prmtf (), программа даст сбой, и ваш друг сделает вывод, что вы плохой программист. Этот цикл нужно переписать следующим образом:

for (i = 0; 1 < mysql num f ields i- s r * 1 i++) {

If (1 > 0)

fputc ( \t , stdout);

printf ( %s , row[i] = NULL ? row[i] : NULL );

fputc (\n, stdout);

Единственным случаем, когда не надо проверять значение столбца на значение NULL , является случай, когда из атрибута этого столбца ясно, что может принимать пустые значения.

Ошибка № 4 - передача бессмысленных результирующих значений

Функции из клиентской библиотеки, ожидающие буферы, предполагают, что они действительно существуют. Вот код, нарушающий этот принцип:

char *from str = some string ; char *to str; unsigned int len;

len = mysql escape string (to str, from str, strlen (from str));

В чем здесь дело? Указатель tostr должен содержать адрес реально существующего буфера В этом примере буфер не существует, и указатель содержит адрес какого-то произвольного места в памяти. Не передавайте не проинициализированный указатель, как это было в примере с аргументом tostr функции mysql escape string {), конечно, если не хотите разгуливать по какой-то произвольной области памяти.



1 ... 100 101 102 [ 103 ] 104 105 106 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика