简单链表实现中的奇怪内存问题 C

问题描述 投票:0回答:1

我正在编写一个简单链表,它具有由 {name, price} 组成的元素结构,并且在我正在实现的某些函数中呈现出一种奇怪的行为。这些功能是: 1 - PopFront(删除列表的最后一个元素) 2 - PopByIndex(给定一个条目索引,它将删除该位置上的元素)

到底发生了什么?好吧,这些函数确实移除了它们应该移除的元素,但它们以某种方式改变了列表中另一个元素的价格值 😕.

例子:

使用前删除功能

Name:        A  Price: 1.00
Name:        B  Price: 2.00
Name:        C  Price: 3.00
Name:        D  Price: 4.00
    --------
     |Menu|
    --------
(1) Add Element in Front
(2) Add Element in Back
(3) Add Element in Position
(4) Remove Element from Front
(5) Remove Element from Back
(6) Remove Element by Position
(7) Print List
(8) Calculate Itens Sum
(0) Exit Program

删除 D 元素后,A 的价格为 0

Name:        A  Price: 0.00
Name:        B  Price: 2.00
Name:        C  Price: 3.00
    --------
     |Menu|
    --------
(1) Add Element in Front
(2) Add Element in Back
(3) Add Element in Position
(4) Remove Element from Front
(5) Remove Element from Back
(6) Remove Element by Position
(7) Print List
(8) Calculate Itens Sum
(0) Exit Program

我用gdb看具体什么时候元素被修改了,发现是我调用free()释放被移除元素地址的内存的时候

最小可复制示例:

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

typedef struct Node Node;
typedef struct List List;

struct Node{
    char name[100];
    float price;
    int code;
    struct Node* prox; 
};

struct List{
    struct Node *head;
    int size;
};

Node* InstantiateNode(){
    Node* new_node = malloc(sizeof new_node);
    new_node->prox = NULL;
    return new_node;
}
void InitNode(Node* node, char* name, float price){
    strcpy(node->name, name);
    node->price = price;
}
void PrintNode(Node node){
    printf("Name: %8s  Price: %.2f\n", node.name, node.price);
}
int EmptyList(List list){
    return list.size == 0 ? 1 : 0;
}
List* InstantiateList(void){
    List* new_list = malloc(sizeof new_list);
    new_list->head = NULL;
    new_list->size = 0;
    return new_list;
}
void InitList(List* list, Node* new_node){
    new_node->prox = list->head;
    list->head = new_node;
    list->size++;
}
void PushFront(List* list, Node* new_node){
    if(EmptyList(*list)){
        InitList(list, new_node);
        return;
    }
    Node* tracker = list->head;
    while(tracker->prox != NULL)
        tracker = tracker->prox;
    tracker->prox = new_node;
    list->size++;
}
void PushBack(List* list, Node* new_node){
        InitList(list, new_node);
}
Node* TrackListbyIndex(List lista, int index){
    if(index > lista.size){
        printf("Unreachable List index \n"); // Warning
        return NULL;
    }
    int cont = 0;
    Node* aux = lista.head;
    while(cont != index){
        aux = aux->prox;
        cont++;
    }
    return aux;
}
void PushByIndex(List* list, Node* new_node, int index){
    if(index==0){
        PushBack(list, new_node);
        return;
    }
    Node* aux = TrackListbyIndex(*list, index-1);
    Node* aux2 = aux->prox;
    if(aux){
        new_node->prox = aux->prox;
        aux->prox = new_node;
        list->size++;
    }
}

void PopFront(List* list){
    if(EmptyList(*list))
        return;
    Node* aux = list->head;
    Node *tracker, *tracker_next;
    tracker = list->head;
    if(tracker->prox != NULL){
        tracker_next = tracker->prox;
        while(tracker_next->prox != NULL){
            tracker = tracker_next;
            tracker_next = tracker_next->prox;
        }    
        tracker->prox = NULL;
        aux = tracker_next;
    }
    if(aux == list->head){
        list->head = NULL;
    }
    free(aux);
    list->size--;
}
void PopBack(List* list){
    if(EmptyList(*list))
        return;
    Node* aux = list->head;
    list->head = list->head->prox;
    free(aux);
    list->size--;   
}
void PopByIndex(List* list, int index){
    if(index==0){
        PopBack(list);
        return;
    }
    //if(index+1== list->size){
    //    PopFront(list);
    //    return;
    //}
    Node *aux, *aux_next;
    aux = TrackListbyIndex(*list, index-1);
    if(aux){
    aux_next = aux->prox;
    aux->prox = aux_next->prox;
    free(aux_next);
    list->size--;
    }
}

void PrintList(List list){
    Node* tracker = list.head;
    while(tracker != NULL){
        PrintNode(*tracker);
        tracker = tracker->prox;
    }
}

void Menu(void);
void HandleMenu(int);

int main(void){
    int option;
    for(;;){
        Menu();
        printf("Type your choosen:");
        scanf("%d", &option);
        system("clear");
        HandleMenu(option);
    }
    return 0;
}

void Menu(void){
    printf("\t--------\n");
    printf("\t |Menu|\n");
    printf("\t--------\n");
    printf("(1) Add Element in Front\n");
    printf("(2) Add Element in Back\n");
    printf("(3) Add Element in Position\n");
    printf("(4) Remove Element from Front\n");
    printf("(5) Remove Element from Back\n");
    printf("(6) Remove Element by Position\n");
    printf("(7) Print List\n");
    printf("(8) Calculate Itens Sum\n");
    printf("(0) Exit Program\n");
}
void HandleMenu(int option){
    static List * market_list = NULL;
    Node* new_node = NULL;
    char node_name[100];
    float node_price;
    int index;
    if(market_list == NULL)
       market_list = InstantiateList();
    switch(option){
        case 0:
            exit(1);
            break;
        case 1:
            new_node = InstantiateNode();
            printf("Type the product's name: ");
            scanf(" %[^\n]", node_name);
            printf("Type the product's price: ");
            scanf("%f", &node_price);
            InitNode(new_node, node_name, node_price);
            PushFront(market_list, new_node);
            printf("Item Added\n");
            break;
        case 2:
            new_node = InstantiateNode();
            printf("Type the product's name: ");
            scanf(" %[^\n]", node_name);
            printf("Type the product's price: ");
            scanf("%f", &node_price);
            InitNode(new_node, node_name, node_price);
            PushBack(market_list, new_node);
            printf("Item Added\n");
            break;
        case 3:
            new_node = InstantiateNode();
            printf("Type the product's name: ");
            scanf(" %[^\n]", node_name);
            printf("Type the product's price: ");
            scanf("%f", &node_price);
            InitNode(new_node, node_name, node_price);
            printf("Type Index: ");
            scanf("%d", &index);
            PushByIndex(market_list, new_node, index-1);
            printf("Item Added\n");
            break;

        case 4:
            PopFront(market_list);
            break;
        case 5:
            PopBack(market_list);
            break;
        case 6:
            printf("Type Index: ");
            scanf("%d", &index);
            PopByIndex(market_list, index-1);
            break;
        case 7:
            PrintList(*market_list);
            break;
    }
}
c memory data-structures singly-linked-list
1个回答
1
投票
  1. InstantiateNode()
    Node *
    分配空间,但您想要为
    Node
    分配空间:
Node *new_node = malloc(sizeof *new_node);
  1. InstantiateList()
    List *
    分配空间,但您想要为
    List
    分配空间:
List *new_list = malloc(sizeof *new_list);

这两个更改之后是删除后的输出:

Name:        A  Price: 1.00
Name:        B  Price: 2.00
Name:        C  Price: 3.00
© www.soinside.com 2019 - 2024. All rights reserved.