繁体   English   中英

C中数组和指针的段错误

[英]Segmentation Fault in Array and Pointer in 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,"\",\"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;
}

问题是在

 strcat(postData,CPID);

postData 指向的postData既不可修改也没有足够的空间来容纳连接的字符串。

你需要

  • 使postData成为一个数组,其维度足以容纳连接的字符串。
  • 使用分配器函数( malloc()和系列)分配足够的 memory 并将该指针存储在postData中。

strcat()手册页添加

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

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

您是 1) 写给 memory 的,您不允许修改; 2) 写给不属于您的 memory。

这里

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

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

strcat(postData,CPID);

这会将 append 字符串CPID转换为字符串文字。 换句话说 - 它将通过覆盖其字符串终止字符来修改字符串文字,并且它会将部分CPID复制到紧跟在字符串文字之后的 memory 中。 两种操作均无效。

您需要的是使postData指向可以修改的 memory。

修复 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;

这两个修复的缺点是固定的 memory 大小(即 8192 个字符)。 memory 对于您要发布的数据是否总是足够的?

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

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

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

所以总结一下:

如果您知道要发布的数据的大小上限并且限制很小,您可以使用简单的 Fix 1 go。

否则我会推荐修复 2。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM