编程语言 C 中的分配
Alloc in programming language C
我将 XDK Bosch 传感器用于一个用 C 语言编程的项目。我的想法是 XDK 应该能够连接到另一个网络。 SSID 和密码通过 MQTT 发送。已经可以在初始化时将 XDK 连接到网络。为了接收 MQTT 消息,使用了下面显示的函数,该函数部分由 Guides of Bosch 改编。每当收到 MQTT 消息时,都会执行此函数。
- 目标:连接到新的 Wifi 网络
我收到的消息总是如下所示:IP_Address/SSID/Password/
例如192.155.125.146/TestSSID/TestPassword/
已测试:函数本身正确接收内容
已测试:CountNumberItemsPwd
、CountNumberItemsSSID
和CountNumberItemsIp
正确计算密码、SSID和IP地址的字符数
对数组 arraySSID
、arrayPW
和 arrayIp
使用 printf
显示正确的内容
假定问题:传递给将 XDK 连接到新网络的函数的字符数组的大小似乎需要适当调整大小。我尝试使用过大的 char 数组但没有成功。因此,我目前正在尝试在 alloc
的帮助下解决问题。不幸的是,我无法让它工作,也找不到我用 alloc
.
做错了什么
#define COMMON_BUFFER_SIZE 255
char MQTT_BROKER_HOST[] = "192.111.111.111";
char message_received [COMMON_BUFFER_SIZE];
/**
* @brief Event handler for incoming publish MQTT data
*
* @param[in] publishData
* Event Data for publish
*/
static void HandleEventIncomingPublish(
MqttPublishData_T publishData)
{
char published_topic_buffer[COMMON_BUFFER_SIZE];
char published_data_buffer[COMMON_BUFFER_SIZE];
static int incoming_message_count = 0;
//storing topic and incoming data
strncpy(published_data_buffer, (const char *)publishData.payload, sizeof(published_data_buffer));
strncpy(published_topic_buffer, publishData.topic.start, sizeof(published_topic_buffer));
//If the message differs from the one received before, connect to new network
if (message_received != published_data_buffer)
{
//Store message in message_received
strcpy(message_sent, published_data_buffer);
//For While-Loop
int counterForArray = 0;
//For writing content into correct arrays
int BooleanForIP = 0;
int BooleanForPw = 0;
int BooleanForSSID = 0;
int CountCycles = 0; //For Array Access
//Counting of how many items IP Address, SSID and Password consist of
int CountNumberItemsIp = 0;
int CountNumberItemsPW = 0;
int CountNumberItemsSSID = 0;
//Buffer Arrays
char IP_new[20] = "";
char PW_new[50] = "";
char SSID_new[25] = "";
while (counterForArray < COMMON_BUFFER_SIZE)
{
//Check if IP Address has been successfully received
if (message_received[counterForArray] == '/' && BooleanForIP == 0 && BooleanForSSID == 0 && BooleanForPw == 0)
{
BooleanForIP = 1;
CountNumberItemsIp = CountCycles;
CountCycles = 0;
}
//Checking if SSID has been successfully received
else if (message_received[counterForArray] == '/' && BooleanForIP == 1 && BooleanForSSID == 0 && BooleanForPw == 0)
{
BooleanForSSID = 1;
CountNumberItemsSSID = CountCycles;
CountCycles = 0;
printf("Stage 2 reached \n");
}
//Checking if Password has been successfully received
else if (message_received[counterForArray] == '/' && BooleanForIP == 1 && BooleanForSSID == 1 && BooleanForPw == 0)
{
BooleanForPw = 1;
CountNumberItemsPW = CountCycles;
CountCycles = 0;
}
if (BooleanForIP == 0 && BooleanForPw == 0 && BooleanForSSID == 0)
{
IP_new[CountCycles] = message_received[counterForArray];
CountCycles = CountCycles + 1;
}
else if (BooleanForIP == 1 && BooleanForPw == 0 && BooleanForSSID == 0 && message_received[counterForArray] != '/')
{
SSID_new[CountCycles] = message_received[counterForArray];
CountCycles = CountCycles + 1;
}
else if (BooleanForIP == 1 && BooleanForPw == 0 && BooleanForSSID == 1 && message_received[counterForArray] != '/')
{
PW_new[CountCycles] = message_received[counterForArray];
CountCycles = CountCycles + 1;
}
counterForArray = counterForArray + 1;
}
//Dynamic memory
char *arraySSID;
arraySSID = (char*)calloc(CountNumberItemsSSID, sizeof(char));
char *arrayIP;
arrayIP = (char*)calloc(CountNumberItemsIp, sizeof(char));
char *arrayPW;
arrayPW = (char*)calloc(CountNumberItemsPW, sizeof(char));
//Copying content
int SSID = 0;
while (SSID <= CountNumberItemsSSID)
{
arraySSID[SSID] = SSID_new[SSID];
SSID = SSID + 1;
}
int PW = 0;
while (PW <= CountNumberItemsPW)
{
arrayPW[PW] = PW_new[PW];
PW = PW + 1;
}
int IP = 0;
while (IP <= CountNumberItemsIp)
{
arrayIP[IP] = IP_new[IP];
IP = IP + 1;
}
//Disconnecting from old Wifi
//Functions provided by Bosch
Retcode_T retStatusDisconnect = (Retcode_T) WlanConnect_Disconnect(0);
retcode_t DisconnectMQTT = Disconnect();
Retcode_T connect_rc3 = NetworkSetup(&arraySSID, &arrayPW);
if (connect_rc3 == RETCODE_OK)
{
printf("success \n");
}
else
{
Retcode_RaiseError(connect_rc3);
}
//Checking if content has been sent correctly
printf("%s :arraySSID \n",arraySSID);
printf("%s :arrayPW \n",arrayPW);
printf("%s :arrayIP \n",arrayIP);
printf("%s: SSID \n", SSID_new);
printf("%s: IP \n", IP_new);
printf("%s: PW \n", PW_new);
//Deallocate space
free(arraySSID);
free(arrayPW);
free(arrayIP);
}
//Print received message
printf("%s \n", message_received);
incoming_message_count++;
}
如果我在上面的函数中使用以下代码而不是 arraySSID
和 arrayPwd
,即使 arraySSID
和 arrayPwd
,我也能够连接到新网络当我在控制台上打印时显示与 testSSID
和 testPW
相同的内容。
char testSSID[] = "TestSSID";
char testPW[] = "TestPwsd";
Retcode_T connect_rc3 = NetworkSetup(&testSSID, &testPW);
如果我比较arraySSID
、arrayPwd
和testSSID
和testPwd
的size
,则分配给它们的大小不同。 arraySSID
、arrayPwd
的大小始终为 4
。
为此,我使用了以下代码:
printf("%i \n", sizeof(arraySSID));
printf("%i \n", sizeof(testSSID));
printf("%d \n", sizeof(arrayPW));
printf("%d \n", sizeof(testPW));
我想指出几个问题。
- C 中的 sizeof() 有点神奇。它不打印动态分配内存的大小。相反,您最好从代码中打印 CountNumberItemsSSID。
- 另一件事是,在 C 语言中,您需要以空字符结尾的字符串。因此,当您以这种方式计算字节数并且希望输出为有效字符串时,请始终允许 1 个额外字符并确保它是 '\0'.
- 你的填充逻辑,我肯定你正在通过覆盖所有字符串的分配内存来破坏内存。通过为 arraySSID 分配 CountNumberItemsSSID 字节,您只能从 0 写入到 (CountNumberItemsSSID-1),而不是 arraySSID[CountNumberItemsSSID],就像您在 while() 循环中所做的那样。它们绝对应该是 (SSID < CountNumberItemsSSID)。
如果您解决了众多问题中的一部分,我相信它应该可以正常工作。
问题确实是一个指针问题..通过使用
Retcode_T connect_rc3 = NetworkSetup(arraySSID, arrayPW);
该功能运行良好。我没有考虑到 arrayPW
已经是 char *
类型,因此 &arraySSID
是 char **
.
类型
我也把(IP <= CountNumberItemsIp)
改成了(IP < CountNumberItemsIp)
。
我将 XDK Bosch 传感器用于一个用 C 语言编程的项目。我的想法是 XDK 应该能够连接到另一个网络。 SSID 和密码通过 MQTT 发送。已经可以在初始化时将 XDK 连接到网络。为了接收 MQTT 消息,使用了下面显示的函数,该函数部分由 Guides of Bosch 改编。每当收到 MQTT 消息时,都会执行此函数。
- 目标:连接到新的 Wifi 网络
我收到的消息总是如下所示:
IP_Address/SSID/Password/
例如192.155.125.146/TestSSID/TestPassword/
已测试:函数本身正确接收内容
已测试:
CountNumberItemsPwd
、CountNumberItemsSSID
和CountNumberItemsIp
正确计算密码、SSID和IP地址的字符数对数组
arraySSID
、arrayPW
和arrayIp
使用printf
显示正确的内容假定问题:传递给将 XDK 连接到新网络的函数的字符数组的大小似乎需要适当调整大小。我尝试使用过大的 char 数组但没有成功。因此,我目前正在尝试在
做错了什么alloc
的帮助下解决问题。不幸的是,我无法让它工作,也找不到我用alloc
.#define COMMON_BUFFER_SIZE 255 char MQTT_BROKER_HOST[] = "192.111.111.111"; char message_received [COMMON_BUFFER_SIZE]; /** * @brief Event handler for incoming publish MQTT data * * @param[in] publishData * Event Data for publish */ static void HandleEventIncomingPublish( MqttPublishData_T publishData) { char published_topic_buffer[COMMON_BUFFER_SIZE]; char published_data_buffer[COMMON_BUFFER_SIZE]; static int incoming_message_count = 0; //storing topic and incoming data strncpy(published_data_buffer, (const char *)publishData.payload, sizeof(published_data_buffer)); strncpy(published_topic_buffer, publishData.topic.start, sizeof(published_topic_buffer)); //If the message differs from the one received before, connect to new network if (message_received != published_data_buffer) { //Store message in message_received strcpy(message_sent, published_data_buffer); //For While-Loop int counterForArray = 0; //For writing content into correct arrays int BooleanForIP = 0; int BooleanForPw = 0; int BooleanForSSID = 0; int CountCycles = 0; //For Array Access //Counting of how many items IP Address, SSID and Password consist of int CountNumberItemsIp = 0; int CountNumberItemsPW = 0; int CountNumberItemsSSID = 0; //Buffer Arrays char IP_new[20] = ""; char PW_new[50] = ""; char SSID_new[25] = ""; while (counterForArray < COMMON_BUFFER_SIZE) { //Check if IP Address has been successfully received if (message_received[counterForArray] == '/' && BooleanForIP == 0 && BooleanForSSID == 0 && BooleanForPw == 0) { BooleanForIP = 1; CountNumberItemsIp = CountCycles; CountCycles = 0; } //Checking if SSID has been successfully received else if (message_received[counterForArray] == '/' && BooleanForIP == 1 && BooleanForSSID == 0 && BooleanForPw == 0) { BooleanForSSID = 1; CountNumberItemsSSID = CountCycles; CountCycles = 0; printf("Stage 2 reached \n"); } //Checking if Password has been successfully received else if (message_received[counterForArray] == '/' && BooleanForIP == 1 && BooleanForSSID == 1 && BooleanForPw == 0) { BooleanForPw = 1; CountNumberItemsPW = CountCycles; CountCycles = 0; } if (BooleanForIP == 0 && BooleanForPw == 0 && BooleanForSSID == 0) { IP_new[CountCycles] = message_received[counterForArray]; CountCycles = CountCycles + 1; } else if (BooleanForIP == 1 && BooleanForPw == 0 && BooleanForSSID == 0 && message_received[counterForArray] != '/') { SSID_new[CountCycles] = message_received[counterForArray]; CountCycles = CountCycles + 1; } else if (BooleanForIP == 1 && BooleanForPw == 0 && BooleanForSSID == 1 && message_received[counterForArray] != '/') { PW_new[CountCycles] = message_received[counterForArray]; CountCycles = CountCycles + 1; } counterForArray = counterForArray + 1; } //Dynamic memory char *arraySSID; arraySSID = (char*)calloc(CountNumberItemsSSID, sizeof(char)); char *arrayIP; arrayIP = (char*)calloc(CountNumberItemsIp, sizeof(char)); char *arrayPW; arrayPW = (char*)calloc(CountNumberItemsPW, sizeof(char)); //Copying content int SSID = 0; while (SSID <= CountNumberItemsSSID) { arraySSID[SSID] = SSID_new[SSID]; SSID = SSID + 1; } int PW = 0; while (PW <= CountNumberItemsPW) { arrayPW[PW] = PW_new[PW]; PW = PW + 1; } int IP = 0; while (IP <= CountNumberItemsIp) { arrayIP[IP] = IP_new[IP]; IP = IP + 1; } //Disconnecting from old Wifi //Functions provided by Bosch Retcode_T retStatusDisconnect = (Retcode_T) WlanConnect_Disconnect(0); retcode_t DisconnectMQTT = Disconnect(); Retcode_T connect_rc3 = NetworkSetup(&arraySSID, &arrayPW); if (connect_rc3 == RETCODE_OK) { printf("success \n"); } else { Retcode_RaiseError(connect_rc3); } //Checking if content has been sent correctly printf("%s :arraySSID \n",arraySSID); printf("%s :arrayPW \n",arrayPW); printf("%s :arrayIP \n",arrayIP); printf("%s: SSID \n", SSID_new); printf("%s: IP \n", IP_new); printf("%s: PW \n", PW_new); //Deallocate space free(arraySSID); free(arrayPW); free(arrayIP); } //Print received message printf("%s \n", message_received); incoming_message_count++; }
如果我在上面的函数中使用以下代码而不是 arraySSID
和 arrayPwd
,即使 arraySSID
和 arrayPwd
,我也能够连接到新网络当我在控制台上打印时显示与 testSSID
和 testPW
相同的内容。
char testSSID[] = "TestSSID";
char testPW[] = "TestPwsd";
Retcode_T connect_rc3 = NetworkSetup(&testSSID, &testPW);
如果我比较arraySSID
、arrayPwd
和testSSID
和testPwd
的size
,则分配给它们的大小不同。 arraySSID
、arrayPwd
的大小始终为 4
。
为此,我使用了以下代码:
printf("%i \n", sizeof(arraySSID));
printf("%i \n", sizeof(testSSID));
printf("%d \n", sizeof(arrayPW));
printf("%d \n", sizeof(testPW));
我想指出几个问题。
- C 中的 sizeof() 有点神奇。它不打印动态分配内存的大小。相反,您最好从代码中打印 CountNumberItemsSSID。
- 另一件事是,在 C 语言中,您需要以空字符结尾的字符串。因此,当您以这种方式计算字节数并且希望输出为有效字符串时,请始终允许 1 个额外字符并确保它是 '\0'.
- 你的填充逻辑,我肯定你正在通过覆盖所有字符串的分配内存来破坏内存。通过为 arraySSID 分配 CountNumberItemsSSID 字节,您只能从 0 写入到 (CountNumberItemsSSID-1),而不是 arraySSID[CountNumberItemsSSID],就像您在 while() 循环中所做的那样。它们绝对应该是 (SSID < CountNumberItemsSSID)。
如果您解决了众多问题中的一部分,我相信它应该可以正常工作。
问题确实是一个指针问题..通过使用
Retcode_T connect_rc3 = NetworkSetup(arraySSID, arrayPW);
该功能运行良好。我没有考虑到 arrayPW
已经是 char *
类型,因此 &arraySSID
是 char **
.
我也把(IP <= CountNumberItemsIp)
改成了(IP < CountNumberItemsIp)
。