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

数组中的分段错误和C中的指针,c,string,curl,segmentation-fault,strcat,C,String,Curl,Segmentation Fault,Strcat,我正在用数组和指针编写程序,结果出现了这个分段错误。有人能解释为什么我在这段代码中出现了这种分段错误吗 我的代码: #include <stdio.h> #include <curl/curl.h> #include <string.h> int main(void) { CURL *curl; CURLcode res; struct curl_slist *headers = NULL; ch

我正在用数组和指针编写程序,结果出现了这个分段错误。有人能解释为什么我在这段代码中出现了这种分段错误吗

我的代码:

#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,"\",\"option\":{\"attribute\":false,\"setting\":false,\"protocol\":false,\"device\":false,\"sdkConfig\":false,\"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;
}
#包括
#包括
#包括
内部主(空)
{
卷曲*卷曲;
卷曲编码;
struct curl_slist*headers=NULL;
char CPID[50]=“98f5b52a59aa4503999894c10bc33dca”;
char Uni_ID[10]=“Demo123”;
char*postData;
curl=curl_easy_init();
if(curl)
{
curl\u easy\u setopt(curl,CURLOPT\u URL,“https://avnetagent.iotconnect.io/api/2.0/agent/sync");
卷曲位置(卷曲,卷曲位置,1L);
//postData=“{\'cpId\”:\”+cpId+“\”,\“uniqueId\”:\“+Uni\u 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、“\”、“option\”:{“attribute\”:false、““setting\”:false、““protocol\”:false、““device\”:false、““sdkConfig\”:false、““rule\”:false}”);
headers=curl\u slist\u append(headers,“Accept:application/json”);
headers=curl\u slist\u append(headers,“内容类型:application/json”);
curl_easy_setopt(curl,CURLOPT_HTTPHEADER,headers);
curl_easy_setopt(curl,CURLOPT_POSTFIELDS,postData);
/*执行请求,res将获得返回代码*/
res=旋度(curl)\u容易执行(curl);
/*检查错误*/
如果(res!=卷曲(OK)
fprintf(stderr,“curl\u easy\u perform()失败:%s\n”,
卷曲(容易的);
/*总是清理*/
旋度\轻松\清洁(旋度);
}
返回0;
}
问题出在

 strcat(postData,CPID);
postData
指向的内存既不可修改,也没有足够的空间容纳连接的字符串

你要么

  • 使
    postData
    数组的维数足以容纳连接的字符串
  • 使用分配器函数(
    malloc()
    和family)分配足够的内存,并将该指针存储在
    postData
要添加,请从

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

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

您正在1)写入不允许修改的内存,2)写入不属于您的内存

这里

将指针
postData
设置为指向字符串文字,即不允许修改的常量字符串。然而,你知道

strcat(postData,CPID);
它将字符串
CPID
附加到字符串文本。换句话说,它将通过覆盖字符串终止字符来修改字符串文字,并进一步将
CPID
的部分内容复制到字符串文字之后的内存中。这两个操作都无效

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

修复1:

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

postData = "{\"cpId\":\""; --->   strcpy(postData, "{\"cpId\":\"");
char *postData;            --->   char *postData = malloc(8192);
                                  assert(postData != NULL);

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

return 0;                  --->   free(postData);
                                  return 0;
修复2:

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

postData = "{\"cpId\":\""; --->   strcpy(postData, "{\"cpId\":\"");
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]在大多数系统上是一个问题,因为它们对具有自动存储持续时间的变量有大小限制

因此,总结如下:

如果您知道要发布的数据的大小上限,并且该上限非常小,那么可以使用简单的修复1


否则,我将推荐修复2。

我是指针新手。你能给我解释一下或者在我的代码中更正一下吗?我想答案涵盖了所有要求的要点。请试一试,如果有什么不对劲,请回来。在这里,“免费做我的工作”的要求是不受欢迎的。谢谢,;)。我尝试了对我有效的修复1。