Return 来自函数的指针,然后释放指针
Return a pointer from a function, then free the pointer
我正在尝试从命令行 argv[]
处理多个名称,然后添加或删除以“+”或“-”开头的所述名称。 IE +bill +ted -ted 将添加 bill 和 ted,然后删除 ted。我可以毫无问题地将名称添加到此列表,但我的 removeNode()
函数调用导致分段错误。在我的 main() 中,当我转到要删除的进程名称时,我将 char * name
设置为等于 removeNode()
的 return 指针,这应该是来自被释放节点的字符串。 return 这个指针的正确方法是什么,这样我就可以从命令行中删除我引用的名称?我还包含了我的插入功能。
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);
}
}
}
导致错误的问题是您使用的是
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
我正在尝试从命令行 argv[]
处理多个名称,然后添加或删除以“+”或“-”开头的所述名称。 IE +bill +ted -ted 将添加 bill 和 ted,然后删除 ted。我可以毫无问题地将名称添加到此列表,但我的 removeNode()
函数调用导致分段错误。在我的 main() 中,当我转到要删除的进程名称时,我将 char * name
设置为等于 removeNode()
的 return 指针,这应该是来自被释放节点的字符串。 return 这个指针的正确方法是什么,这样我就可以从命令行中删除我引用的名称?我还包含了我的插入功能。
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);
}
}
}
导致错误的问题是您使用的是
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