c - C语言中的分配

标签 c memory-management alloc

我正在将 XDK 博世传感器用于一个用 C 语言编程的项目。这个想法是 XDK 应该能够连接到另一个网络。 SSID 和密码通过 MQTT 发送。初始化时就可以将 XDK 连接到网络。为了接收 MQTT 消息,使用了下面所示的函数,该函数部分由 Bosch Guides 改编。每当收到 MQTT 消息时,就会执行此函数。

  • 目标:连接到新的 Wifi 网络
  • 我收到的消息始终如下所示:IP_Address/SSID/Password/ 例如192.155.125.146/TestSSID/TestPassword/

  • 已测试:函数本身正确接收内容

  • 已测试:CountNumberItemsPwdCountNumberItemsSSIDCountNumberItemsIp 可以正确计算 Pwd、SSID 和 IP 地址的字符数

  • 对数组 arraySSIDarrayPWarrayIp 使用 printf 显示正确的内容

  • 假设问题:传递给将 XDK 连接到新网络的函数的字符数组的大小似乎需要正确调整大小。我尝试使用超大的字符数组但没有成功。因此,我目前正在尝试借助 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++;
            }
    

如果我在上面的函数中使用以下代码而不是 arraySSIDarrayPwd,即使 arraySSID 我也能够连接到新网络当我在控制台上打印时, > 和 arrayPwd 显示与 testSSIDtestPW 相同的内容。

 char testSSID[] = "TestSSID";
 char testPW[] = "TestPwsd";
 Retcode_T connect_rc3 = NetworkSetup(&testSSID, &testPW);

如果我比较arraySSIDarrayPwd以及testSSIDtestPwdsize >,为它们分配不同的大小。 arraySSIDarrayPwd 的大小始终为 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 中,您需要字符串以 null 结尾。因此,当您以这种方式计算字节时,如果您希望输出是有效的字符串,请始终允许 1 个额外字符并确保其为“\0”。
  • 您的填充逻辑,我确信您通过覆盖所有字符串分配的内存来破坏内存。通过为 arraySSID 分配 CountNumberItemsSSID 字节,您只能从 0 到 (CountNumberItemsSSID-1) 写入,而不是像在 while() 循环中那样写入 arraySSID[CountNumberItemsSSID]。它们绝对应该是 (SSID < CountNumberItemsSSID)。

如果您解决了许多问题中的一些问题,我相信它应该可以正常工作。

关于c - C语言中的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50077782/

相关文章:

C - 段错误 - 链表的 insert_sort 函数

c - 允许用户搜索排序的名称列表的程序卡住

ios - 如果在循环中分配,会创建多少个对象

objective-c - 子类调用父类的方法

c++ - 为什么在抛出 'std::bad_alloc' 实例后调用终止?

c - 这个用 C 编写的程序没有给出正确的输出

C++ stringstream to char* 转换内存分配

c++ - 分配内存和保留内存有什么区别?

c++ - 需要管理一 block 'theoretical'内存的slab

c++ - MATLAB 在执行半色调 mex 包装函数时崩溃?