如何为查询字符串正确分配内存?

时间:2014-05-30 03:15:45

标签: c postgresql malloc

我需要在C程序中执行sql查询。我使用libpq连接到Postgresql。

char *formatted_query = "SELECT * FROM table LIMIT %d OFFSET %d";
char *query;
PGconn *conn;
PGresult *res;
int limit;
int offset;
/* here is connect to base get some data from user (like limit, offset etc.) */
sprintf(query, formatted_query, limit, offset);
res = PQexec(conn, query);

问题在于我不知道如何为query分配足够的内存 我当然可以这样做:

char query[999]; 

但我认为这种方式是错误的。如果我这样做:

char *query = (char *)malloc(sizeof(char) * sizeof(formatted_query));

可能会发生分配的内存不足(例如,限制或偏移将是MAX_INT)。 如何为查询字符串正确分配内存?

2 个答案:

答案 0 :(得分:1)

你应该真的使用PQexecParams。对于整数,遗憾的是你仍然需要将它们格式化为文本,但是你可以使用一个简单的静态缓冲区。

PGconn *conn;
PGresult *res;

#define MAX_INT4_DIGITS 11

const char *query = "SELECT * FROM table LIMIT $1 OFFSET $2";
Oid paramtypes[] = {INT4OID, INT4OID};
char *paramvalues[2];
char limitstr[MAX_INT4_DIGITS];
char offsetstr[MAX_INT4_DIGITS];

snprintf(offsetstr, MAX_INT4_DIGITS, "%d", limit);
snprintf(limitstr, MAX_INT4_DIGITS, "%d", offset); 

paramvalues[0] = limitstr;
paramvalues[1] = offsetstr;

res = PQexecParams(conn, query, 2, paramtypes, paramvalues, NULL, NULL, 0);

当你只有几个整数参数时,使用参数化查询并不是什么大不了的事,但是当你使用用户提供的字符串时它变得至关重要。否则,你会因引用和逃避SQL注入而陷入可怕的混乱中。

libpq二进制协议接口实际上更方便,但遗憾的是它不适用于不同的架构(字节序,字大小等)。

为了更方便地使用libpq自动化一些低级别的界面,请查看libpqtypes

答案 1 :(得分:0)

你可以计算两个数字的符号数,但最简单的方法是:

// max 32 bit unsigned integer number is 4294967295 (10 symbols)
int maxPossibleStringLength = strlen(formatted_query) + 2*10 + 1; // don't forget 0 symbol at end
char *query = (char *)malloc(sizeof(char) * maxPossibleStringLength);