我正在用数组和指针执行程序,但遇到了这个分段错误。有人能解释为什么我在这段代码中出现了这个分段错误吗。
我的代码:
#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: %sn",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}
问题出在中
strcat(postData,CPID);
由CCD_ 1指向的存储器既不可修改。
你需要选择
- 使
postData
是一个维数足以容纳连接字符串的数组 - 使用分配器函数(
malloc()
和系列(分配足够的内存,并将指针存储在postData
中
添加,从strcat()
手册页
char *strcat(char *dest, const char *src);
strcat()
函数将src
字符串附加到dest
字符串,覆盖postData
1末尾的终止空字节(' '
(,然后添加一个终止空字节。字符串不能重叠,并且dest
字符串必须有足够的空间来容纳结果。如果dest
不够大,则程序行为是不可预测的;[…]
您正在1(写入不允许修改的内存,2(写入不属于您的内存。
此处
postData = "{"cpId":"";
您将指针postData
设置为指向字符串文字,即不允许修改的常量字符串。然而,你做
strcat(postData,CPID);
其将把字符串CCD_ 15附加到字符串文字中。换句话说,它将通过覆盖字符串终止字符来修改字符串文字,并且它将在字符串文字之后将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
(仅适用于"Fix 2"(。
注意,使用";固定1";具有非常高的内存量,例如char postData[8192000];
在大多数系统上是一个问题,因为它们对具有自动存储持续时间的变量有大小限制。
因此得出结论:
如果您知道要发布的数据的大小上限,并且这个限制很小,那么您可以使用简单的Fix 1。
否则,我建议修复2。