编写了一个程序"麻烦票",允许用户创建带有各种参数的故障票。代码使用struct ticket {}
来存储票证数据。每向tkt_array
添加一个new_ticket。代码是相当长的,所以我张贴了相关的文件和代码片段。这不是学校的项目,而是我个人对学习c的兴趣。
总之,有函数create_ticket()
和update_ticket()
使用_strdup()
来处理用户输入。这是我的理解,_strdup()
使用malloc()
,这需要调用free()
的内存。我的方法是在程序退出时调用free()
,并假设这将释放malloc()占用的内存。此任务由free_tkt_arr()
函数完成。
create_ticket()
函数在设置name
、problem
、assigned_to
和status
指针时使用_strdup()
。
函数update_ticket()
也使用_strdup()
来更新name
,problem
,assigned_to
和status
。
代码退出时,调用free_tkt_arr()
函数释放_strdup()
分配的内存。
我想知道在系统退出时调用free_ticket()
是否会释放在create_ticket()
和update_ticket()
中调用_strdup()
所分配的所有内存?
struct ticket {
int priority;
int number;
char *name;
char *problem;
char *assigned_to;
char *status;
};
函数create_ticket()
在设置name
,problem
,assigned_to
和status
指针时使用_strdup()
:
struct ticket tkt_array[NUM_TICKETS];
void create_ticket() {
char *ptr;
struct ticket new_ticket;
printf("Enter your name: ");
new_ticket.name = _strdup(get_input(20));
printf("Enter problem description: ");
new_ticket.problem = _strdup(get_input(100));
printf("Assigned to: ");
new_ticket.assigned_to = _strdup(get_input(20));
//printf("Enter ticket status: ");
//using _strdup() in case status is updated using _strdup which requires call to free()
ptr = "new";
new_ticket.status = _strdup(ptr);
}
函数update_ticket()
也使用_strdup()
来更新name
,problem
,assigned_to
和status
票。
void update_ticket() {
printf("Enter ticket number: ");
ptr = get_input(8);
sscanf_s(ptr, "%d", &ticket_num);
if (*ptr == '1') {
printf("Updating Status.n");
printf("Enter Status update: ");
tmp_ticket2.status = _strdup(get_input(20));
} else
if (*ptr == '2') {
printf("Updating Problem description.n");
printf("Enter Problem description update. ");
tmp_ticket2.problem = _strdup(get_input(100));
} else
if (*ptr == '3') {
printf("Updating Assigned to.n");
printf("Enter Assigned to update. ");
tmp_ticket2.assigned_to = _strdup(get_input(20));
}
}
函数free_tkt_array()
在退出代码时被调用,应该被调用释放之前调用_strdup()
所分配的内存
void free_tkt_arr() {
for (int i = 0; i <= tkt_count - 1; i++) {
free(tkt_array[i].assigned_to);
free(tkt_array[i].name);
free(tkt_array[i].problem);
free(tkt_array[i].status);
}
}
我想过下载和学习valgrind,但这可能有点超出我的能力范围。
是否应该释放字符串取决于get_input()
做什么。如果get_input()
返回一个已分配的内存块,则不需要调用strdup()
。
请注意,您应该使用strdup()
而不是_strdup()
:
-
_strdup()
是Microsoft特有的函数,可能实现了与POSIX标准函数strdup()
相同的语义。 -
strdup()
在Unix系统上可用,在POSIX中指定。它将成为即将到来的C2x版本C标准的一部分(最终)。 -
如果
strdup()
在您的系统中不可用,您可以使用宏或这样定义它:#include <stdlib.h> #include <string.h> char *strdup(const char *s) { size_t size = strlen(s) + 1; char *p = malloc(size); if (p) { return memcpy(p, s, size); } else { return p; } }
您可以free()
内存,但您也有传递NULL
到指针,如果你不释放与结构相关的内存(似乎是这种情况)。当您在静态全局内存中分配一个结构体数组时,您将使它们全部初始化为NULL
,因此不需要初始化指针来检查它们是否已被分配。但过了一段时间就不适用了,所以一旦你不使用它们,你最好把memset(3)
或bzero(3)
改成你的结构。您没有展示如何区分已使用的记录和未使用的记录,但是如果您使用指针字段作为标志将其标记为未使用,那么您必须在释放票据后将其设置为NULL
。如果不这样做,使您的指针继续指向未分配的内存(可能由malloc(3)
分配给其他方式,这对您的程序来说是灾难性的事情)
你知道,free(ptr)
不能使指针ptr
变成NULL
,因为每个参数在c中都是按值传递的,所以free(ptr);
后面跟着ptr = NULL;
是一个很好的选择。
顺便说一句,有一个最小的,可复制的例子可以很好地搜索任何其他可能的错误。