从函数返回一个指针,然后释放指针
Posted
技术标签:
【中文标题】从函数返回一个指针,然后释放指针【英文标题】:Return a pointer from a function, then free the pointer 【发布时间】:2022-01-07 14:15:45 【问题描述】:我尝试从命令行argv[]
处理多个名称,然后添加或删除以“+”或“-”开头的名称。 IE +bill +ted -ted 将添加 bill 和 ted 然后删除 ted。我可以毫无问题地将名称添加到此列表中,但我的 removeNode()
函数调用会导致分段错误。在我的 main() 中,当我转到要删除的进程名称时,我将 char * name
设置为等于 removeNode()
的返回指针,它应该是来自被释放节点的字符串。返回此指针的正确方法是什么,以便我可以从命令行中删除我引用的名称?我还包括了我的插入功能。
int insert(struct node ** head, char * name)
struct node * newNode = (struct node * ) malloc(sizeof(struct node));
newNode -> data = name;
newNode -> next = NULL;
struct node * current = * head;
if ( * head == NULL)
* head = newNode;
return 1;
while (current -> next != NULL)
current = current -> next;
current -> next = newNode;
return 1;
char * removeNode(struct node ** head, char * name)
struct node * current = * head;
struct node * previous;
if (current == NULL)
return "error0";
if (strcmp(current -> data, name) == 0)
char * data = current -> data;
* head = current -> next;
free(current);
printf("Removed %s \n", name);
return data;
while (current != NULL)
previous = current;
current = current -> next;
if (strcmp(current -> data, name) == 0)
char * data = current -> data;
previous -> next = current -> next;
free(current);
printf("Removed %s \n", name);
return data;
return "error0";
int main(int argc, char * argv[])
printf("Author : Torin Costales \n");
struct node * head = NULL;
for (int x = 1; x < argc; x++)
if (argv[x][0] == '+')
char * name = malloc((strlen(argv[x] + 1) + 1));
if (name == NULL) return EXIT_FAILURE;
strcpy(name, argv[x]);
printf("adding %s \n", name);
insert( & head, name);
printf("List: ");
printList( & head);
else if (argv[x][0] == '-')
printf("removing %s \n", argv[x] + 1);
char * name = removeNode( & head, argv[x] + 1);
free(name);
printList( & head);
【问题讨论】:
从removeNode
释放返回值会导致很大的问题,因为返回值有时是"error0"
。另外,不用两行代码分配空间并将argv[x]复制到name
,只需使用char *name = strdup(argv[x]);
样式指南:点.
和箭头->
运算符绑定非常紧密,因为它们是postfix operators。它们的周围不应有空格。写current -> data
不是惯用的C 语言,表示编码器是一个tyro(新手)。使用current->data
。
【参考方案1】:
导致错误的问题是您正在使用
strcpy(name, argv[x]);
你应该使用的地方
strcpy(name, argv[x] + 1);
这导致在尝试删除 ted
时返回由 "error0"
生成的字符串,因为列表包含 +bill
和 +ted
。
已修复和清理:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
char *data;
struct node *next;
node;
void printList(struct node *node) // Don't need a pointer to a pointer.
printf("List:");
for (; node; node = node->next)
printf(" %s", node->data);
printf("\n");
// Returns 0 on success.
// Returns -1 and sets errno on error.
int append(struct node **node_pp, char *name) // Better name
while (*node_pp)
node_pp = &( (*node_pp)->next );
struct node *newNode = malloc(sizeof(struct node));
if (!newNode)
return -1;
newNode->data = name;
newNode->next = NULL;
*node_pp = newNode;
return 0;
// Returns NULL if not found.
char *removeNode(struct node **node_pp, const char *name) // Added `const`
for (; *node_pp; next_p = &( (*node_pp)->next ))
if (strcmp((*node_pp) -> data, name) == 0)
struct node * oldNode = *next_p;
*node_pp = oldNode->next;
char *data = oldNode->data;
free(oldNode);
return data;
return NULL; // NULL is a far better value to return on error.
int main(int argc, char * argv[])
struct node *head = NULL;
for (int x = 1; x < argc; x++)
if (argv[x][0] == '+')
char *name = strdup(argv[x] + 1); // Simpler
if (name == NULL)
perror("Can't allocate memory"); // Error message is good
exit(EXIT_FAILURE);
printf("Appending %s.\n", name);
if (append(&head, name) < 0)
perror("Can't append node to list");
exit(EXIT_FAILURE);
else if (argv[x][0] == '-')
const char *name_to_find = argv[x] + 1;
printf("Removing %s.\n", name_to_find);
char *name = removeNode(&head, name_to_find);
if (name) // Do check if it was found!
free(name);
else
printf("%s not found\n", name_to_find);
printList(head);
printf("\n");
+foo +bar -baz -foo
的输出:
Appending foo.
List: foo
Appending bar.
List: foo bar
Removing baz.
baz not found
List: foo bar
Removing foo.
List: bar
【讨论】:
以上是关于从函数返回一个指针,然后释放指针的主要内容,如果未能解决你的问题,请参考以下文章
为啥free函数不在释放内存后,将指针置NULL,野指针有啥用
C 语言结构体 ( 结构体中嵌套一级指针 | 分配内存时先 为结构体分配内存 然后再为指针分配内存 | 释放内存时先释放 指针成员内存 然后再释放结构头内存 )