C中数组和指针的分段错误

我正在使用数组和指针进行程序,但出现此分段错误。谁能解释为什么我在这段代码中遇到这种分段错误。

我的代码:

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
int main(void)
{
        CURL *curl;
        CURLcode res;
        struct curl_slist *headers = NULL;
        char CPID[50] = "98f5b52a59aa4503999894c10bc33dca" ;
        char Uni_ID[10] = "Demo123" ;
        char *postData;
        curl = curl_easy_init();
        if(curl)
        {
                curl_easy_setopt(curl,CURLOPT_URL,"https://avnetagent.iotconnect.io/api/2.0/agent/sync");
                curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L);
                //postData = "{\"cpId\":\""+CPID+"\",\"uniqueId\":\""+Uni_ID+"\",\"option\":{\"attribute\":false,\"setting\":false,\"protocol\":false,\"device\":false,\"sdkConfig\":false,\"rule\":false}}";
                postData = "{\"cpId\":\"";
                strcat(postData,CPID);
                strcat(postData,"\",\"uniqueId\":\"");
                strcat(postData,Uni_ID);
                strcat(postData,\"rule\":false}}");

                headers = curl_slist_append(headers,"accept: application/json");
                 headers = curl_slist_append(headers,"Content-Type: application/json");

                curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
                curl_easy_setopt(curl,CURLOPT_POSTFIELDS,postData);
                /* Perform the request,res will get the return code */
                res = curl_easy_perform(curl);
                /* Check for errors */
                if(res != CURLE_OK)
                fprintf(stderr,"curl_easy_perform() failed: %s\n",curl_easy_strerror(res));

                /* always cleanup */
                curl_easy_cleanup(curl);
        }
        return 0;
}
iCMS 回答:C中数组和指针的分段错误

问题出在

 strcat(postData,CPID);

postData指向的内存既不可修改,也没有足够的空间来容纳串联的字符串。

您需要

  • 使postData的维数组足以容纳级联字符串。
  • 使用分配器函数(malloc()和家族)分配足够的内存,并将该指针存储在postData中。

要添加,请从strcat() man page

char *strcat(char *dest,const char *src);

strcat()函数将src字符串追加到dest字符串,覆盖{{1}末尾的终止空字节('\0') },然后添加一个终止的空字节。字符串可能不会重叠,并且dest字符串必须有足够的空间用于结果。如果dest不够大,则程序行为是不可预测的; [...]

,

您是1)写不允许修改的内存,以及2)写不属于您的内存。

这里

postData = "{\"cpId\":\"";

您将指针postData设置为指向字符串文字,即不允许您修改的常量字符串。但是,您

strcat(postData,CPID);

,它将在字符串文字后附加字符串CPID。换句话说,它将通过覆盖字符串终止符来修改字符串文字,并进一步将CPID的一部分复制到字符串文字之后的内存中。两项操作均无效。

您需要做的是使postData指向可以修改的内存。

修复1:

char *postData;            --->   char postData[8192];

postData = "{\"cpId\":\""; --->   strcpy(postData,"{\"cpId\":\"");

修复2:

char *postData;            --->   char *postData = malloc(8192);
                                  assert(postData != NULL);

postData = "{\"cpId\":\""; --->   strcpy(postData,"{\"cpId\":\"");

return 0;                  --->   free(postData);
                                  return 0;

这两个修复程序的缺点是固定的内存大小(即8192个字符)。那将永远足够存储您要发布的数据吗?

如果您知道上限,则可以设置一个固定大小(就像我一样)。

如果您不知道上限,则必须更改代码,以便可以在运行时增加分配的内存,例如使用realloc(仅适用于“修复2”)。

请注意,使用“ Fix 1”具有很高的内存量,例如char postData[8192000];在大多数系统上都是一个问题,因为它们具有自动存储持续时间的变量的大小限制。

因此得出结论:

如果您知道要发布的数据的大小上限,并且合理地小,则可以使用简单的Fix 1。

否则,我会建议您修复2。

本文链接:https://www.f2er.com/1844457.html

大家都在问