我有一个结构
struct request { int code; char *message; };
我想要正确地自由。
我有以下function来做到这一点:
void free_request(struct request *req) { if (req->message != NULL) { free(req->message); } free(req); req = NULL; }
问题是当我尝试释放使用字符串文字创建的请求时,我从编译器得到“free():invalid pointer”/ segfault错误:
struct request *req; req = malloc(sizeof(struct request)); req->message = "TEST"; free_request(req);
因为我想在不同的地方创建请求结构,一旦使用文字(在客户端)和一次使用我从套接字读取的*字符(在服务器端)我想知道是否有一个函数来确保我不要试图释放文字,同时仍允许我释放我使用malloc创建的消息。
没有标准函数可以让您知道指针是否是动态分配的。 你应该在你的结构中包含一个标志来告知你自己,或者只使用动态分配的字符串(在这种情况下strdup
是你的朋友)。 根据您的网络设置,使用strdup
可能更简单(好吧,说实话,根本不使用strdup
)。
随着strdup
:
struct message* req; req = malloc(sizeof *req); req->message = strdup("TEST"); free_request(req);
带旗帜:
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);
此外,在创建对象时,不要忘记将已分配的内存归零。 这可以为你节省很多麻烦。
req = malloc(sizeof *req); memset(req, 0, sizeof *req);
那,并从free_request
设置req
为NULL
将不会有任何影响。 您需要获取struct message**
或在函数调用后自己执行。
没有办法判断你是否正在使用字符串文字(嗯,你可以将字符串文字放在由GCC创建的自定义.section中,然后检查字符串指针以确定它是否包含在文字的.section中)。 但是……使用简单的编程模式有一种更好的方法。
用文字分配
正常情况。 对free(req)的调用将按预期工作:释放请求结构。
struct *req; req = malloc(sizeof(*req)); req->message = "TEST";
动态字符串分配
在下文中, some_string
是您希望存储为请求消息的字符串。 它可以是文字的,也可以是动态分配的。 这在分配struct本身时为字符串分配内存(并且在释放struct时将自动释放)。
struct *req; req = malloc(sizeof(*req)+strlen(some_string)+1); req->message = (char *)&req[1]; strcpy(req->message, some_string);
释放
free(req);
编辑:一般情况
请注意,上面针对dynamic string
的分配方案是通用的,即使您不知道some_string
是否为文字,也可以使用它。 因此,一个处理这两种情况的单一函数,以及free()
释放可以解决特殊情况。
我建议在struct request
添加一个成员来指示request :: message是否是动态分配的,并在分配request::message
的同时设置该成员,然后在释放内存之前检查它。 它在C中有点乱。
请注意,不仅是会导致问题的字符串文字,任何指向未通过malloc()或calloc()在堆上动态分配的数据的指针都会失败,因此只需检测“如果char指向C中的字符串文字” *即使它可以轻松完成也无济于事。
它是段错误的,因为包含"TEST"
的内存位置(通常)是只读的而不是位于堆上(通常是因为它驻留在程序的某些只读部分)。 只给出一个char*
指针,你将无法知道它是否指向free()
able字符串。 相反,您应该为req->message
分配一个缓冲区并复制字符。
char* str = "TEST"; int len = strlen(str); req->message = malloc(len+1); strcpy(req->message, str);
或者,您可以使用zneak建议的strdup()
。
如果你只是想确保释放malloc的内存,你可以打电话
realloc(req->message,(size_t)0)
如果内存库实现是健壮的,它应该工作。
看一下:
struct request *req; req = calloc(1,sizeof(struct request)); strcpy(req->message = malloc(strlen("TEST")+1),"TEST"); free_request(req);
它严格符合ANSI C标准。 strdup不是ANSI C.
req = NULL;
是多余的。
以上就是c/c++开发分享如何检查char *是否指向C中的字符串文字相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/560567.html