如何检查char*是否指向C中的字符串文字

Nik*_*las 20 c string free

我有一个结构

struct request {
  int code;
  char *message;
};
Run Code Online (Sandbox Code Playgroud)

我想要正确地自由.

我有以下功能来做到这一点:

void free_request(struct request *req) {
  if (req->message != NULL) {
      free(req->message);
  }
  free(req);
  req = NULL;
}
Run Code Online (Sandbox Code Playgroud)

问题是,我得到一个"免费():无效的指针" /段错误错误从编译器,当我尝试释放已使用字符串文字创造了一个请求:

struct request *req;
req = malloc(sizeof(struct request));
req->message = "TEST";
free_request(req);
Run Code Online (Sandbox Code Playgroud)

因为我想在不同的地方创建请求结构,一旦使用文字(在客户端)和一次使用我从套接字读取的*字符(在服务器端)我想知道是否有一个函数来确保我不要尝试释放文字,同时仍允许我释放我使用malloc创建的消息.

zne*_*eak 24

没有标准函数可以让您知道指针是否动态分配.你应该在你的结构中包含一个标志来告知你自己,或者只使用动态分配的字符串(strdup在这种情况下你的朋友).根据您的网络设置,这可能是简单的使用strdup(嗯,说实话,这简单的使用strdup的话).

strdup:

struct message* req;
req = malloc(sizeof *req);
req->message = strdup("TEST");
free_request(req);
Run Code Online (Sandbox Code Playgroud)

带旗帜:

struct message
{
    int code;
    char* message;
    bool isStatic; // replace to 'char' if bool doesn't exist
};

void free_request(struct message* req)
{
    if (!req->isStatic) free(req->message);
    free(req);
}

struct message* req;
req = malloc(sizeof *req);
req->message = "TEST";
req->isStatic = 1;
free_request(req);
Run Code Online (Sandbox Code Playgroud)

此外,在创建对象时,不要忘记将已分配的内存归零.这可以为你节省很多麻烦.

req = malloc(sizeof *req);
memset(req, 0, sizeof *req);
Run Code Online (Sandbox Code Playgroud)

那,并设置reqNULLfrom free_request将不会有任何影响.您需要struct message**在函数调用后自己执行或自己执行此操作.

  • 可以使用`calloc`而不是`malloc`和`memset`. (3认同)
  • @Niklas:如果你想让它变得更容易,你应该自己创建一个函数来创建请求对象,并从那里开始.这样您的客户就不必担心管理您的记忆. (3认同)

Noa*_*ins 5

没有办法判断你是否在使用字符串文字(嗯,你可以将字符串文字放在由GCC创建的自定义.section中,然后检查字符串指针以确定它是否包含在文字的.section中).但是......使用简单的编程模式有更好的方法.

用文字分配

正常情况.对free(req)的调用将按预期工作:释放请求结构.

struct *req;

req = malloc(sizeof(*req));
req->message = "TEST";
Run Code Online (Sandbox Code Playgroud)

动态字符串分配

在下面,some_string是您希望存储为请求消息的字符串.它可以是文字的,也可以是动态分配的.这在分配struct本身时为字符串分配内存(并且在释放struct时将自动释放).

struct *req;

req = malloc(sizeof(*req)+strlen(some_string)+1);
req->message = (char *)&req[1];
strcpy(req->message, some_string);
Run Code Online (Sandbox Code Playgroud)

释放

free(req);
Run Code Online (Sandbox Code Playgroud)

编辑:一般情况

请注意,上面的分配方案dynamic string是通用的,即使您不知道是否some_string是文字,也可以使用它.因此,一个功能可以处理这两种情况,并可以free()解决特殊情况.