gpt4 book ai didi

c - 可疑的内存管理影响

转载 作者:行者123 更新时间:2023-12-01 09:32:05 24 4
gpt4 key购买 nike

<分区>

因此,为了巩固我对 C 中指针和内存管理的理解,我决定对链表进行基本实现。

虽然我对我的代码中的某些事情非常怀疑,并且想知道我是否可以得到一些澄清。一、代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//Doubly-linked lists brah
typedef struct ll_int {
struct ll_int* prev;
int value;
struct ll_int* next;
} ll_int_t;

ll_int_t* newNode(int value) {
//Allocate the memory
ll_int_t* new = (ll_int_t*) malloc(sizeof(ll_int_t));

//If it was not successfully created, exit
if (new == NULL) {
fprintf(stderr, "Unable to allocate memory for new LL node\n");
exit(EXIT_FAILURE);
}

//Set up the node
new->value = value;
new->prev = NULL;
new->next = NULL;
return new;
}

void addElement(ll_int_t* head, int value) {
//Check if the head is in fact the end of the list
if (head->next == NULL) {
ll_int_t* new = newNode(value);
head->next = new;
new->prev = head;
} else {
addElement(head->next, value);
}
}

int lenList(ll_int_t* head) {
int i = 1;
ll_int_t* curr = head;
while ((curr = curr->next) != NULL) i++;
free(curr);
return i;
}

void delHead(ll_int_t** list) {
if (*list != NULL && lenList(*list) > 1) {
ll_int_t* dead = *list;
*list = (*list)->next;
(*list)->prev = NULL;
free(dead);
}
}

bool delElementAt(ll_int_t** list, int pos) {
if (pos == 0) {
delHead(list);
return true;
} else {
//TODO: Implement
}
}

void printLL(ll_int_t** list) {
//We could be clever and traverse back to the start if we're not
//given the head of the list... but that's /effort/
if ((*list)->prev != NULL) {
printf("That is not the head of the Linked List!\n");
return;
}

int i = 0;
ll_int_t* curr = *list;
do {
printf("(%d): %d\n", i++, curr->value);
} while((curr = curr->next) != NULL); //sneaky
free(curr);
}

int main (int argc, char** argv) {
ll_int_t* head = newNode(5);
addElement(head, 10);
printf("lenList: %d\n", lenList(head));
addElement(head, 15);
printf("lenList: %d\n", lenList(head));
addElement(head, 20);
printf("lenList: %d\n", lenList(head));
printLL(&head);
delElementAt(&head, 0);
printLL(&head);
return(EXIT_SUCCESS);
}

让我挑出一些痛点:

所以最初,我的 addElement 函数看起来像:

void addElement(ll_int_t* head, int value) {
//Attempt to create the new node
ll_int_t* new = newNode(value);

//Check if the head is in fact the end of the list
if (head->next == NULL) {
head->next = new;
new->prev = head;
} else {
ll_int_t* curr = head->next;
while (curr->next != NULL) curr = curr->next;
curr->next = new;
new->prev = curr;
}
}

但我很担心 ll_int_t* curr,因为它感觉像是一个不必要的副本。所以我将其更改为使用尾递归:

void addElement(ll_int_t* head, int value) {
//Check if the head is in fact the end of the list
if (head->next == NULL) {
ll_int_t* new = newNode(value);
head->next = new;
new->prev = head;
} else {
addElement(head->next, value);
}
}

这让我感到更快乐,但我想我的问题是,我真的在这里取得了什么成就吗?

此外,我在 lenListprintLL 中的 free() 是否真的有必要,或者函数范围是否为我处理了这个?

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com