根据this answer,不应删除常量,因为常量可能不会首先分配。但是,在某些情况下,我想保护动态分配的数据。例如,在管理用户会话†时,我想确保像当前用户名这样的数据不会被其他功能意外覆盖,但是在从中解析会话数据时确实会分配这些数据。请求。
这是一个代码示例,可以帮助您更好地理解。但是请记住,事情已经大大简化了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *request = "www.example.com/index?first-name=SOME&last-name=DUDE";
char *get_username_from_request(const char *req) {
char *first_name = strstr(req, "first-name") + strlen("first-name") + 1;
char *last_name = strstr(req, "last-name") + strlen("last-name") + 1;
char *username = malloc(10);
memcpy(username, first_name, 4);
username[4] = ' ';
memcpy(username + 5, last_name, 4);
/* The returned string is "SOME DUDE" */
return username;
}
int main(void) {
char *username = get_username_from_request(request);
printf("Welcome, %s.\n", username);
free(username);
return 0;
}
我真的想改用const char *username = get_username_from_request(request);
,但是当我进行此更改时,Clang会发出警告:
/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/nalzok/CLionProjects/zero/cmake-build-debug --target zero -- -j 2
Scanning dependencies of target zero
[ 50%] Building C object CMakeFiles/zero.dir/main.c.o
/Users/nalzok/CLionProjects/zero/main.c:24:10: warning: passing 'const char *' to parameter of type 'void *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
free(username);
^~~~~~~~
/usr/include/stdlib.h:151:18: note: passing argument to parameter here
void free(void *);
^
1 warning generated.
[100%] Linking C executable zero
[100%] Built target zero
任何想法都值得赞赏。
†:好,believe it or not,我正在用C编写Web应用程序。
答案 0 :(得分:2)
首先,您必须了解,没有任何事情可以阻止编译后的代码覆盖任何数据,无论是否声明为const
。 const
的正确性仍然可以帮助您发现代码中的逻辑错误,所以这是一个好主意。
对于您的具体问题,我建议在此处隐藏一些类似OOP的信息。您可以例如为用户会话建模:
session.h :
#ifndef SESSION_H
#define SESSION_H
typedef struct Session Session;
Session *Session_create(void);
int Session_setUsername(Session *self, const char *username);
const char *Session_Username(const Session *self);
void Session_destroy(Session *self);
#endif
session.c :
#include <stdlib.h>
#include <string.h>
#include "session.h"
struct Session
{
char *username;
};
Session *Session_create(void)
{
Session *self = calloc(1, sizeof *self);
return self;
}
int Session_setUsername(Session *self, const char *username)
{
free(self->username);
self->username = malloc(strlen(username) + 1);
if (!self->username) return -1;
strcpy(self->username, username);
return 0;
}
const char *Session_Username(const Session *self)
{
return self->username;
}
void Session_destroy(Session *self)
{
if (!self) return;
free(self->username);
free(self);
}
现在,如果您的代码中有const Session *
,您将无法操作任何会话数据。您只能获得指向您的用户名的const
指针。