i want to understand how dynamic memory allocation done for result of sqlite3_get_table with malloc ?
-
wrote on 7 Mar 2022, 09:07 last edited by Qt embedded developer 3 Jul 2022, 09:29
I have seen that my sqlite query in string format passed to below function
intSettingList=0; memset(sqlQuerySendBuff, 0x00, sizeof (sqlQuerySendBuff)); struct Result_Set table1; sprintf(sqlQuerySendBuff, "SELECT IFNULL(strKey,'0'), IFNULL(strValue,'0') from tblWebSetting where bActive = 1 and bDeleted = 0"); table1 = get_result(sqlQuerySendBuff);
Now i am confused in below malloc based statements
ResultSet get_result(const char* fmt, ...) { int ret = 0; int nrow = 0, ncol = 0, i = 0, j = 0, count = 0; char *err_messg; char **result; char ***recordset; ResultSet resultSet_Table; char RET[10]; char sql_string[QUERY_BUFF_SIZE]; //this honestly needs to be more elegant; will do for now va_list args; va_start(args, fmt); sql_string[0] = '\0'; printf("Temp called 3\n"); ret = vsprintf(sql_string, fmt, args); printf("Temp called 4\n"); va_end(args); printf("\n%s\n", sql_string); //initialize resultSet_Table; resultSet_Table.rows = 0; resultSet_Table.cols = 0; resultSet_Table.recordset = NULL; // if(sqlite3_open("/home/ap/pub/CONFIG.DB", &StructSql) == SQLITE_OK) // { printf("Database Opened\n"); // CTOS_LCDTPrintXY(1, 1, "DB Opened"); ret = sqlite3_get_table( StructSql, sql_string, &result, &nrow, &ncol, &err_messg ); printf("nrow=%d ncol=%d\n", nrow, ncol); recordset = (char ***) malloc(nrow * sizeof (char **)); for (count = ncol; count < ((nrow + 1) * ncol); count++) { printf("Enter in LOOP\n"); recordset[i] = (char **) malloc(ncol * sizeof (char *)); for (j = 0; j < ncol; j++) { printf("%s ", result[count]); recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); strcpy(recordset[i][j], result[count]); if (j != (ncol - 1)) count++; } i++; printf("\n"); } printf("Enter in outer loop\n"); sqlite3_free_table(result); if (ret != SQLITE_OK) { printf("SQL error: %s\n", err_messg); sprintf(RET, "%d", ret); // InsertErrorLog // if (strcmp(strErrorLogDescription, "") != 0) { // InsertErrorlog("", 0, 0, err_messg, strErrorLogDescription); // } success = 0; } else { resultSet_Table.rows = nrow; resultSet_Table.cols = ncol; resultSet_Table.recordset = recordset; success = 1; } // } // if(sqlite3_close(StructSql) == SQLITE_OK) // { // printf("Database Closed\n"); // //CTOS_LCDTPrintXY(1, 2, "DB Closed"); // } memset(strErrorLogDescription, 0x00, sizeof (strErrorLogDescription)); sqlite3_int64 intBeforeReleaseInBG = sqlite3_memory_used(); printf("intBeforeReleaseInBG = %lld\n", intBeforeReleaseInBG); int intReleaseMemory = sqlite3_release_memory(10000); printf("intReleaseMemory = %d\n", intReleaseMemory); sqlite3_int64 intAfterReleaseInBG = sqlite3_memory_used(); //sqlite3_db_release_memory(StructSql); sqlite3_int64 intSoftHeap = sqlite3_soft_heap_limit64(250000); printf("intSoftHeap = %lld\n", intSoftHeap); printf("intAfterReleaseInBG = %lld\n", intAfterReleaseInBG); return resultSet_Table; }
I want to understand why malloc() used like below :
recordset = (char ***) malloc(nrow * sizeof (char **));
recordset[i] = (char **) malloc(ncol * sizeof (char *));
recordset[i][j] = (char *) malloc((strlen(result[count]) + 1));
-
@JonB Yes i know that how to use malloc but what is logic behind memory allocation for result received from sqlite3_get_table ?
recordset = (char ***) malloc(nrow * sizeof (char **));
recordset[i] = (char **) malloc(ncol * sizeof (char *));
recordset[i][j] = (char *) malloc((strlen(result[count]) + 1));
wrote on 7 Mar 2022, 11:08 last edited by JonB 3 Jul 2022, 11:11@Qt-embedded-developer
Well you need to look up the documentation forsqlite3_get_table()
to see what it says! At some level these are required to allocate the area of memory to which the later code is going to do thestrcpy()
s etc. from the result set returned.recordset = (char ***) malloc(nrow * sizeof (char **)); // space for `nrow`s of `char **` recordset[i] = (char **) malloc(ncol * sizeof (char *)); // space for `ncol`s of `char *` recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); // space for the length of a C string in `result[count]`, with its terminating '\0' byte
-
I have seen that my sqlite query in string format passed to below function
intSettingList=0; memset(sqlQuerySendBuff, 0x00, sizeof (sqlQuerySendBuff)); struct Result_Set table1; sprintf(sqlQuerySendBuff, "SELECT IFNULL(strKey,'0'), IFNULL(strValue,'0') from tblWebSetting where bActive = 1 and bDeleted = 0"); table1 = get_result(sqlQuerySendBuff);
Now i am confused in below malloc based statements
ResultSet get_result(const char* fmt, ...) { int ret = 0; int nrow = 0, ncol = 0, i = 0, j = 0, count = 0; char *err_messg; char **result; char ***recordset; ResultSet resultSet_Table; char RET[10]; char sql_string[QUERY_BUFF_SIZE]; //this honestly needs to be more elegant; will do for now va_list args; va_start(args, fmt); sql_string[0] = '\0'; printf("Temp called 3\n"); ret = vsprintf(sql_string, fmt, args); printf("Temp called 4\n"); va_end(args); printf("\n%s\n", sql_string); //initialize resultSet_Table; resultSet_Table.rows = 0; resultSet_Table.cols = 0; resultSet_Table.recordset = NULL; // if(sqlite3_open("/home/ap/pub/CONFIG.DB", &StructSql) == SQLITE_OK) // { printf("Database Opened\n"); // CTOS_LCDTPrintXY(1, 1, "DB Opened"); ret = sqlite3_get_table( StructSql, sql_string, &result, &nrow, &ncol, &err_messg ); printf("nrow=%d ncol=%d\n", nrow, ncol); recordset = (char ***) malloc(nrow * sizeof (char **)); for (count = ncol; count < ((nrow + 1) * ncol); count++) { printf("Enter in LOOP\n"); recordset[i] = (char **) malloc(ncol * sizeof (char *)); for (j = 0; j < ncol; j++) { printf("%s ", result[count]); recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); strcpy(recordset[i][j], result[count]); if (j != (ncol - 1)) count++; } i++; printf("\n"); } printf("Enter in outer loop\n"); sqlite3_free_table(result); if (ret != SQLITE_OK) { printf("SQL error: %s\n", err_messg); sprintf(RET, "%d", ret); // InsertErrorLog // if (strcmp(strErrorLogDescription, "") != 0) { // InsertErrorlog("", 0, 0, err_messg, strErrorLogDescription); // } success = 0; } else { resultSet_Table.rows = nrow; resultSet_Table.cols = ncol; resultSet_Table.recordset = recordset; success = 1; } // } // if(sqlite3_close(StructSql) == SQLITE_OK) // { // printf("Database Closed\n"); // //CTOS_LCDTPrintXY(1, 2, "DB Closed"); // } memset(strErrorLogDescription, 0x00, sizeof (strErrorLogDescription)); sqlite3_int64 intBeforeReleaseInBG = sqlite3_memory_used(); printf("intBeforeReleaseInBG = %lld\n", intBeforeReleaseInBG); int intReleaseMemory = sqlite3_release_memory(10000); printf("intReleaseMemory = %d\n", intReleaseMemory); sqlite3_int64 intAfterReleaseInBG = sqlite3_memory_used(); //sqlite3_db_release_memory(StructSql); sqlite3_int64 intSoftHeap = sqlite3_soft_heap_limit64(250000); printf("intSoftHeap = %lld\n", intSoftHeap); printf("intAfterReleaseInBG = %lld\n", intAfterReleaseInBG); return resultSet_Table; }
I want to understand why malloc() used like below :
recordset = (char ***) malloc(nrow * sizeof (char **));
recordset[i] = (char **) malloc(ncol * sizeof (char *));
recordset[i][j] = (char *) malloc((strlen(result[count]) + 1));
wrote on 7 Mar 2022, 09:53 last edited by JonB 3 Jul 2022, 09:53@Qt-embedded-developer
It is a shame that you are programming with C++ and Qt and still usingmalloc()
. That really belongs in C programs, C++ introducednew
from the outset.Having said that, what is your question?
void *malloc(size_t size)
takes a size in bytes and returns a genericvoid *
. So you specify how many bytes are required for whatever you want to store there, and you cast the returned pointer to whatever you are assigning it to. -
@Qt-embedded-developer
It is a shame that you are programming with C++ and Qt and still usingmalloc()
. That really belongs in C programs, C++ introducednew
from the outset.Having said that, what is your question?
void *malloc(size_t size)
takes a size in bytes and returns a genericvoid *
. So you specify how many bytes are required for whatever you want to store there, and you cast the returned pointer to whatever you are assigning it to.wrote on 7 Mar 2022, 11:04 last edited by@JonB Yes i know that how to use malloc but what is logic behind memory allocation for result received from sqlite3_get_table ?
recordset = (char ***) malloc(nrow * sizeof (char **));
recordset[i] = (char **) malloc(ncol * sizeof (char *));
recordset[i][j] = (char *) malloc((strlen(result[count]) + 1));
-
@JonB Yes i know that how to use malloc but what is logic behind memory allocation for result received from sqlite3_get_table ?
recordset = (char ***) malloc(nrow * sizeof (char **));
recordset[i] = (char **) malloc(ncol * sizeof (char *));
recordset[i][j] = (char *) malloc((strlen(result[count]) + 1));
wrote on 7 Mar 2022, 11:08 last edited by JonB 3 Jul 2022, 11:11@Qt-embedded-developer
Well you need to look up the documentation forsqlite3_get_table()
to see what it says! At some level these are required to allocate the area of memory to which the later code is going to do thestrcpy()
s etc. from the result set returned.recordset = (char ***) malloc(nrow * sizeof (char **)); // space for `nrow`s of `char **` recordset[i] = (char **) malloc(ncol * sizeof (char *)); // space for `ncol`s of `char *` recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); // space for the length of a C string in `result[count]`, with its terminating '\0' byte
-
@Qt-embedded-developer
Well you need to look up the documentation forsqlite3_get_table()
to see what it says! At some level these are required to allocate the area of memory to which the later code is going to do thestrcpy()
s etc. from the result set returned.recordset = (char ***) malloc(nrow * sizeof (char **)); // space for `nrow`s of `char **` recordset[i] = (char **) malloc(ncol * sizeof (char *)); // space for `ncol`s of `char *` recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); // space for the length of a C string in `result[count]`, with its terminating '\0' byte
wrote on 7 Mar 2022, 11:23 last edited by@JonB Sorry may be i am wrong and illogical. can you able tell me this logic is some what similar to 2d array like or 3d array of string like ?
-
@JonB Sorry may be i am wrong and illogical. can you able tell me this logic is some what similar to 2d array like or 3d array of string like ?
wrote on 7 Mar 2022, 11:33 last edited by JonB 3 Jul 2022, 11:38recordset
is a 2D array/table. It holds all the rows, and is indexed by row number. There are a total ofnrow
s allocated.recordset[row]
is one row. It holds an array of the columns in the row. There are a total ofncol
s allocated.recorset[row][col]
is one cell/value, in one column of one row. The column values arechar *
, i.e. C-strings. For each one the length of the string plus 1 byte for'\0'
is alloacted.
rows -> columns -> cells/values of type C-string.
-
recordset
is a 2D array/table. It holds all the rows, and is indexed by row number. There are a total ofnrow
s allocated.recordset[row]
is one row. It holds an array of the columns in the row. There are a total ofncol
s allocated.recorset[row][col]
is one cell/value, in one column of one row. The column values arechar *
, i.e. C-strings. For each one the length of the string plus 1 byte for'\0'
is alloacted.
rows -> columns -> cells/values of type C-string.
wrote on 8 Mar 2022, 05:44 last edited by@JonB Hi can you give example for deallocate memory for recordset ?
-
@JonB Hi can you give example for deallocate memory for recordset ?
wrote on 8 Mar 2022, 10:39 last edited by@Qt-embedded-developer
This is absolutely basic C! If youmalloc()
, what function do you have to call to free the allocated memory? -
@Qt-embedded-developer
This is absolutely basic C! If youmalloc()
, what function do you have to call to free the allocated memory?wrote on 8 Mar 2022, 14:13 last edited by Qt embedded developer 3 Aug 2022, 14:17@JonB i have to call free() to deallocate memory.
void free(void *ptr);
i have to free recordset memory inside below part else condition
if (ret != SQLITE_OK) { printf("SQL error: %s\n", err_messg); sprintf(RET, "%d", ret); // InsertErrorLog // if (strcmp(strErrorLogDescription, "") != 0) { // InsertErrorlog("", 0, 0, err_messg, strErrorLogDescription); // } success = 0; } else { resultSet_Table.rows = nrow; resultSet_Table.cols = ncol; resultSet_Table.recordset = recordset; success = 1; }
-
@JonB i have to call free() to deallocate memory.
void free(void *ptr);
i have to free recordset memory inside below part else condition
if (ret != SQLITE_OK) { printf("SQL error: %s\n", err_messg); sprintf(RET, "%d", ret); // InsertErrorLog // if (strcmp(strErrorLogDescription, "") != 0) { // InsertErrorlog("", 0, 0, err_messg, strErrorLogDescription); // } success = 0; } else { resultSet_Table.rows = nrow; resultSet_Table.cols = ncol; resultSet_Table.recordset = recordset; success = 1; }
wrote on 8 Mar 2022, 14:33 last edited by JonB 3 Aug 2022, 14:34@Qt-embedded-developer
So write the code to callfree()
s corresponding to where you did yourmalloc()
s. What else is there to ask/say? -
@Qt-embedded-developer
So write the code to callfree()
s corresponding to where you did yourmalloc()
s. What else is there to ask/say?wrote on 8 Mar 2022, 14:36 last edited by Qt embedded developer 3 Aug 2022, 14:41i have allocated memory like below so to where and how to write free() for this all allocated memory.
recordset = (char ***) malloc(nrow * sizeof (char **)); for (count = ncol; count < ((nrow + 1) * ncol); count++) { printf("Enter in LOOP\n"); recordset[i] = (char **) malloc(ncol * sizeof (char *)); for (j = 0; j < ncol; j++) { printf("%s ", result[count]); recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); strcpy(recordset[i][j], result[count]); if (j != (ncol - 1)) count++; } i++; printf("\n"); }
in else part if i wrote code like below. is it right ?
```
free(recordset);
for (count = ncol; count < ((nrow + 1) * ncol); count++) {printf("Enter in LOOP\n"); free(recordset[i]); for (j = 0; j < ncol; j++) { free(recordset[i][j]); } i++; printf("\n"); }
-
i have allocated memory like below so to where and how to write free() for this all allocated memory.
recordset = (char ***) malloc(nrow * sizeof (char **)); for (count = ncol; count < ((nrow + 1) * ncol); count++) { printf("Enter in LOOP\n"); recordset[i] = (char **) malloc(ncol * sizeof (char *)); for (j = 0; j < ncol; j++) { printf("%s ", result[count]); recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); strcpy(recordset[i][j], result[count]); if (j != (ncol - 1)) count++; } i++; printf("\n"); }
in else part if i wrote code like below. is it right ?
```
free(recordset);
for (count = ncol; count < ((nrow + 1) * ncol); count++) {printf("Enter in LOOP\n"); free(recordset[i]); for (j = 0; j < ncol; j++) { free(recordset[i][j]); } i++; printf("\n"); }
wrote on 8 Mar 2022, 14:51 last edited by JonB 3 Aug 2022, 14:52@Qt-embedded-developer
No, that is not right.You are freeing the items in the same order as you allocated them. Once you have done
free(recordset)
you must not then dofree(recordset[i])
, and once you have donefree(recordset[i])
you must not then dofree(recordset[i][j])
.Please stop and think about it/why. This is basic C.
free()
things in the opposite order to how you built your structure withmalloc()
. Do notfree()
something if you then go into it to access/free()
something else. -
@Qt-embedded-developer
No, that is not right.You are freeing the items in the same order as you allocated them. Once you have done
free(recordset)
you must not then dofree(recordset[i])
, and once you have donefree(recordset[i])
you must not then dofree(recordset[i][j])
.Please stop and think about it/why. This is basic C.
free()
things in the opposite order to how you built your structure withmalloc()
. Do notfree()
something if you then go into it to access/free()
something else.wrote on 8 Mar 2022, 14:55 last edited by Qt embedded developer 3 Aug 2022, 14:58@JonB means i need to write code like below:
int i = 0; for (count = ncol; count < ((nrow + 1) * ncol); count++) { printf("Enter in LOOP\n"); for (j = 0; j < ncol; j++) { free(recordset[i][j]); } free(recordset[i]); i++; printf("\n"); } free(recordset);
And can you elaborate below sentence:
Do not free() something if you then go into it to access/free() something else. -
@JonB means i need to write code like below:
int i = 0; for (count = ncol; count < ((nrow + 1) * ncol); count++) { printf("Enter in LOOP\n"); for (j = 0; j < ncol; j++) { free(recordset[i][j]); } free(recordset[i]); i++; printf("\n"); } free(recordset);
And can you elaborate below sentence:
Do not free() something if you then go into it to access/free() something else.wrote on 8 Mar 2022, 15:04 last edited by@Qt-embedded-developer
In principle you at least now have thefree()
s in the right order.I don't know why you have an
i
and acount
, whether you go through the right items, and why you use(nrow + 1)
(the+ 1
). But that's a coding issue for you to sort out. I have answered your questions, over to you to implement now.Do not free() something if you then go into it to access/free() something else.
Exactly what I wrote; If you go e.g.
free(recordset); free(recordset[i]); // or anything to `recordset[i]`
think about what state
recordset[i]
might be in after you havefree()
drecordset
. -
@Qt-embedded-developer
In principle you at least now have thefree()
s in the right order.I don't know why you have an
i
and acount
, whether you go through the right items, and why you use(nrow + 1)
(the+ 1
). But that's a coding issue for you to sort out. I have answered your questions, over to you to implement now.Do not free() something if you then go into it to access/free() something else.
Exactly what I wrote; If you go e.g.
free(recordset); free(recordset[i]); // or anything to `recordset[i]`
think about what state
recordset[i]
might be in after you havefree()
drecordset
.wrote on 9 Mar 2022, 05:20 last edited by@JonB said in i want to understand how dynamic memory allocation done for result of sqlite3_get_table with malloc ?:
over to you to implement now
Hi
here below i allocated memory for string element in array index
recordset[i][j] = (char *) malloc((strlen(result[count]) + 1)); -
wrote on 9 Mar 2022, 18:28 last edited by mpergand 3 Oct 2022, 08:53
Yeah good C exercise :)
int rows=2, cols=3; const char* R1[]={"r1 c1","r1 c2","r1,c3"}; const char* R2[]={"r2 c1","r2 c2","r2,c3"}; const char** data[]={ R1,R2}; char*** recordset; // array of pointers (rows) to array of pointers (cols) recordset=(char***) malloc(sizeof(char***)*rows); for (int r = 0; r < rows; ++r) { recordset[r]=(char**) malloc(sizeof(char**)*cols); for (int c = 0; c < cols; ++c) { recordset[r][c]=(char*) malloc(sizeof(char)*(strlen(data[r][c])+1)); strcpy(recordset[r][c],data[r][c]); } } for(int r=0 ; r<rows; r++) std::cout<<recordset[r][0]<<", "<<recordset[r][1]<<", "<<recordset[r][2]<<", "<<std::endl; // delete for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { free(recordset[r][c]); } free(recordset[r]); } free(recordset);
-
Yeah good C exercise :)
int rows=2, cols=3; const char* R1[]={"r1 c1","r1 c2","r1,c3"}; const char* R2[]={"r2 c1","r2 c2","r2,c3"}; const char** data[]={ R1,R2}; char*** recordset; // array of pointers (rows) to array of pointers (cols) recordset=(char***) malloc(sizeof(char***)*rows); for (int r = 0; r < rows; ++r) { recordset[r]=(char**) malloc(sizeof(char**)*cols); for (int c = 0; c < cols; ++c) { recordset[r][c]=(char*) malloc(sizeof(char)*(strlen(data[r][c])+1)); strcpy(recordset[r][c],data[r][c]); } } for(int r=0 ; r<rows; r++) std::cout<<recordset[r][0]<<", "<<recordset[r][1]<<", "<<recordset[r][2]<<", "<<std::endl; // delete for (int r = 0; r < rows; ++r) { for (int c = 0; c < cols; ++c) { free(recordset[r][c]); } free(recordset[r]); } free(recordset);
wrote on 9 Mar 2022, 18:35 last edited by@mpergand said in i want to understand how dynamic memory allocation done for result of sqlite3_get_table with malloc ?:
recordset[r][c]=(char*) malloc(sizeof(char*)); strcpy(recordset[r][c],data[r][c]);
Ummm, really...? ;-)
-
@mpergand said in i want to understand how dynamic memory allocation done for result of sqlite3_get_table with malloc ?:
recordset[r][c]=(char*) malloc(sizeof(char*)); strcpy(recordset[r][c],data[r][c]);
Ummm, really...? ;-)
1/18