2015-09-21 3 views
1

Если я хочу хранить информацию, возвращаемую запросом при вызове обратного вызова, должен ли я сделать глубокую копию каждого параметра в argv или могу ли я с уверенностью предположить, что sqlite3 не освободит его после возврата из обратного вызова? Я использую C как язык программирования.Должен ли я сделать глубокую копию каждого параметра в обратном вызове argv в SQLITE?

static int callback_consult(void *dummy, int argc, char **argv, char **col_name) { 
    res_consult_t * answer = &(global_answer -> consult_res); 
    movie_t *curr_tuple = calloc(sizeof(char), sizeof(movie_t)); 

    /* Should I memcpy ??? */ 
    curr_tuple -> name = argv[0]; 
    curr_tuple -> genre = argv[1]; 
    curr_tuple -> description = argv[2]; 
    curr_tuple -> seats_available = argv[3]; /* Convert to int */ 

    (answer -> movies)[tuple] = curr_tuple; 

    return SQLITE_OK; 
} 
+0

Я думаю, что знаю, что вы просите, но вопрос был бы намного яснее, если бы вы предоставили образец кода C. –

+0

Я только что добавил код @JohnBollinger, который должен быть достаточно ясным. – gibarsin

ответ

1

Я предполагаю, что вы спрашиваете о том, что функция обратного вызова передается sqlite3_exec() может безопасно сделать.

Во-первых, Документах по sqlite3_exec() сказать:

3-й аргумент sqlite3_exec() обратного вызова представляет собой массив указателей на строки, полученные как от sqlite3_column_text(), один для каждого столбца. Если элемент из строки результата равен NULL, то соответствующий указатель строки для обратного вызова sqlite3_exec() является указателем NULL.

Вообще говоря, вы сделать поэтому нужно быть готовыми к столбцам результата быть NULL. Является ли безопасным или подходящим назначать такие NULL s любой конкретной переменной, члену структуры или объединения или элементу массива в вашей программе, является характеристикой вашей программы. Конечно, небезопасно передавать NULL в качестве аргумента для memcpy() или strcpy(), поэтому вам, возможно, потребуется это учесть.

Документы для sqlite3_column_text() добраться до мяча проблемы. В частности, это относится:

Указатели, возвращаемые действительны до тех пор, преобразование типа не происходит, как описано выше, или до sqlite3_step() или sqlite3_reset() или sqlite3_finalize() вызывается. Объем памяти, используемый для хранения строк и BLOB, освобождается автоматически.

С

Интерфейс sqlite3_exec() является удобной оболочкой sqlite3_prepare_v2(), sqlite3_step(), и sqlite3_finalize() [...].

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