通过char数组指针存储的结构成员数据返回垃圾值

时间:2018-08-23 09:21:31

标签: mysql c pointers struct arduino-esp8266

我正在尝试使用MySQL_Connection.h的{​​{1}}和MySQL_Cursor.h在OLED LCD上显示database data

此库的链接为https://github.com/ChuckBell/MySQL_Connector_Arduino>

我能够成功地从ChuckBell获取数据。但是,我希望将数据存储在char数组中,以便以后可以在OLED LCD上显示它们。问题是存储的值总是返回垃圾值。我知道它与char数组指针有关,但是搜索了这么长时间之后,我仍然找不到正确的语法。以下是我的代码段。

首先设置Wifi连接和mysql连接。

mysql database

然后开始循环功能以存储和显示数据库数据。

#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
char query[] = "SELECT * FROM test.assetdemo WHERE RFID = \"048EB25A\"";  //sql query
char* sqldata[11];               //array of char pointer to store the 11 data in the database 

void setup(){
    Serial.begin(115200);
    internetConnect(ssid,pw);                             //connect to Wifi
    conn.connect(server_addr, 3306, user, password);      //connect to mysqldatabase
}

输出如下Click here or view below所示。如您所见,这些值在void loop(){ Serial.println("\nRunning SELECT and printing results\n"); MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn); // Initiate the query class instance cur_mem->execute(query); // Execute the query row_values *row = NULL; // Read the rows and print them do { row = cur_mem->get_next_row(); if (row != NULL) { for (int f = 0; f < cols->num_fields; f++) { sqldata[f] = row->values[f]; Serial.print(f); Serial.print(" "); Serial.println(sqldata[f]); /*This works*/ } Serial.println(); } } while (row != NULL); Serial.println(sqldata[0]); /*This return garbage value*/ delete cur_mem; // frees up memory used delay(5000); } 循环中正确显示(除了第8个是布尔类型,稍后我将对其进行更改)。但是,当我退出循环并再次打印该值时,它将返回垃圾值do while应该返回sqldata[0]

048EB25A

下面的代码段显示了Running SELECT and printing results 0 048EB25A 1 Blood Pressure Monitor 2 NA 3 WelchAllyn 503-0054-03 4 010720 5 NA 6 NA 7 Blood Pressure Cuff 8 9 Yes 10 1 ⸮

中的struct声明
MySQL_Cursor.h

我的一部分知道 typedef struct { char *db; char *table; char *name; } field_struct; // Structure for storing result set metadata. typedef struct { int num_fields; // actual number of fields field_struct *fields[MAX_FIELDS]; } column_names; // Structure for storing row data. typedef struct { char *values[MAX_FIELDS]; } row_values; 是造成垃圾值的原因。当指针仅指向地址时,该值将更改。如何静态存储变量,以便在sqldata[f] = row->values[f];之后,该值将保持不变? 先生和女士,请解释这个谜。

PS:我对数组和指针感到困惑,甚至在涉及struct时也感到困惑。

3 个答案:

答案 0 :(得分:2)

解释是,内存在get_next_row函数https://github.com/ChuckBell/MySQL_Connector_Arduino/blob/master/src/MySQL_Cursor.cpp中释放了

memcpy

第二次尝试获取行 free_row_buffer

答案 1 :(得分:0)

由于@Jabberwocky和@rantan pan的建议,我自己能够找到解决方案。他们为我提供了在哪里寻找解决方案的指导。 通过如下所示编辑sqldata,我能够将字符串而不是指针存储到sqldata中。

如下所示重新声明sqldata。

char **sqldata = new char*[11];     //to store 11 data for each query executed
for ( int i = 0; i < 11; i++ )
{
    sqldata[i] = new char[11];
}

然后将sqldata[f] = row->values[f];替换为strcpy(sqldata[f], (*row).values[f]);

现在一切正常。是时候在OLED LCD上打印此废话了。 再次感谢大家!

答案 2 :(得分:0)

@TK Ooi的解决方案还可以,但是作为改进,我将更安全地存储要存储数据的数组的大小,因此可以代替使用

int numberRows = 11;
char **sqldata = new char*[numberRows];
for(int i = 0; i < numberRows; i++ ) {
    sqldata[i] = new char[numberChars];
}
strcpy(sqldata[f], (*row).values[f]);`

更好地将char *数组声明为全局数组,但在查询函数中执行以下操作:

int numberChars = strlen((*row).values[f]);
sqldata[f] = new char[numberChars]; // implies already extra place for null terminator
snprintf(sqldata[f], strlen(sqldata[f]), "%s", (*row).values[f]);`

这样,我们将始终为阵列分配确切的长度,以存储恢复的数据。请注意,使用numberChars代替strlen(sqldata[f])将失败,因为您需要根据存储在sqldata中的类型传递长度:int和{{ 1}} ...