在其他函式中初始化
阿新 • • 發佈:2019-02-01
當我們給指標申請記憶體空間的時候,我們正常使用下面的程式碼
char *p = NULL;
p = (char*)malloc(5);
free(p);
p = NULL;
但是我遇到的問題是,當前不知道需要分配的大小,只能把這個指標傳遞給子函式,在子函式中malloc並賦值。
於是就出現了以下的錯誤程式碼:
int init_err(char *pp)
{
pp = (char*)malloc(10);
}
int main()
{
char *p = NULL;
init_err(p);
free(p);
p = NULL;
return 0;
}
這麼寫是錯的,此時p是空的(NULL),不能free,而且p也沒法使用。
似懂非懂,闡述一下我的想法。在init_err(char *pp)中,指標pp其實已經不是原來的p了,pp只是指向了p的地址,你給pp開闢了記憶體,跟p沒有關係。
無意間瞟了一眼sqlite3的介面,明白了,正確的程式碼應該是這樣:
#include <stdio.h> #include <stdlib.h> #include <string.h> int init(char **p) { *p = (char*)malloc(10); } int main() { char *p = NULL; p = (char*)malloc(5); p[0] = '1'; p[1] = '1'; p[2] = '1'; p[3] = '1'; p[4] = '\0'; printf("%s\n", p); free(p); p = NULL; init(&p); p[0] = 'a'; p[1] = 'a'; p[2] = 'a'; p[3] = 'a'; p[4] = 'b'; p[5] = 'b'; p[6] = 'b'; p[7] = 'b'; p[8] = '\0'; printf("%s\n", p); free(p); p = NULL; return 0; }
中間加了一些賦值語句。用一個二級指標做形參,存放實際的p的記憶體地址。
回過頭來看寫sqlite的程式碼:
errmsg和res在API中都是通過取地址傳遞的。char *errmsg = NULL; char sql[256]; char **res; int row = 0, column = 0; ret = sqlite3_get_table(db, sql, &res, &row, &column, &errmsg); if (ret != SQLITE_OK) { printf("sqlite err (%d): %s\n", ret, errmsg); sqlite3_free(errmsg); return CHK_ERR; } else { } sqlite3_free_table(res);