链表基本插入功能

时间:2019-01-18 08:41:46

标签: c linked-list

我编写了一个程序,该程序获得一些值并将其放入排序的链表中。 问题是输入第一个值后 程序停止 而且甚至没有运行插入功能

我知道问题出在将参数传递给insert函数 但是我不知道如何解决。

save

结果:

/用户/ Danial / CLionProjects /示例/ cmake-build-debug /示例 输入您的值3

进程以退出代码11完成

4 个答案:

答案 0 :(得分:0)

在这里声明NULL并将其设置为struct record *headptr = NULL;

insert

然后将其传递给insert(headptr, data);

ptr

因此,insert中的NULLvoid insert(struct record *ptr, int value)

curptr = ptr;

然后,您设置curptr,因此NULLwhile (value >= (curptr->data)) { 。然后它在此行崩溃:

curptr

因为您正在尝试访问NULL所指向的内存,此时内存为headptr

我的猜测是,您想先将insert的内存分配给NULL。或者处理指针在insert中为$ cat test-cm.yaml apiVersion: v1 data: key1: value1 key2: value2 "": value3 kind: ConfigMap metadata: name: test-cm $ kubectl apply -f test-cm.yaml The ConfigMap "test-cm" is invalid: data[]: Invalid value: "": a valid config key must consist of alphanumeric characters, '-', '_' or '.' (e.g. 'key.name', or 'KEY_NAME', or 'key-name', regex used for validation is '[-._a-zA-Z0-9]+') $ 的情况。

答案 1 :(得分:0)

如果将指针传递给函数,则尽管可以更改指针指向的内容,但不能修改指针,但要实现此目的,必须将指针传递给指针:

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

struct record{
    int data;
    struct record *nextptr;
};

void insert (struct record** ptr, int value);
void printList(struct record *ptr);

int main() {
    struct record *headptr = NULL;
    for (int i = 0; i < 4; ++i) {
        int data;
        printf("Enter your value");
        scanf("%d", &data);
        insert(&headptr, data);
    }
    printList(headptr);
    return 0;
}

void insert (struct record** ptr, int value) {
    if ( ptr == NULL ) {
    //Do nothing ptr is invalid
        return;  
    } 
    printf("WE ARE IN THE INSERT FUNCTION");
    struct record* curptr = *ptr
                ,* newptr = (struct record *) malloc(sizeof(struct record));
    newptr->data = value;
    //Check curptr isn't NULL
    while(curptr != NULL && value >= (curptr->data)){
        curptr = curptr->nextptr;
    }
    if (curptr == NULL) {
        newptr->nextptr = NULL;
        *ptr = newptr;
    } else {
        newptr->nextptr = curptr;
    }
}

void printList(struct record *ptr){
    while(ptr->nextptr != NULL) {
        printf("%d", ptr->data);
        ptr = ptr->nextptr;
    }
}

答案 2 :(得分:0)

insert有两个大问题。首先,您将ptr作为指针struct record传递。发生这种情况时,您的insert函数会收到一个指针的副本,该指针指向内存中的相同位置,但自身具有不同的地址,与从main()。这与您在insert中对指针的副本所做的操作无关紧要,这些更改将永远不会在main()中看到,因为您正在操作副本,而不会返回任何值。要解决该问题,请设置参数struct record **并传递main()中指针的地址。

您在insert中遇到的下一个最大问题是,在开始之前,您无法检查curptr是否为NULL(因为它将是对insert的第一次呼叫)开始取消对curptr的引用-可能导致段错误或工厂的其他运行未定义行为。

创建链接列表时,必须满足两个不同的测试条件:

  1. 我要插入第一个节点吗? (如果是这样,只需分配`* ptr = newptr);和
  2. 所有其他插入操作都需要您根据value的{​​{1}}进行迭代以找到合适的2节点以在其中插入数据。

您可以简单地处理这两种情况:

data

在您编写的分配内存的任何程序中,必须保留一个指向分配的每个块的开头的指针,以便在不再需要该内存时可以将其释放。通常,您将需要编写一个 rec_t *curptr = *ptr, *newptr = malloc (sizeof *newptr); if (!newptr) { perror ("malloc-newptr"); return; } newptr->data = value; newptr->nextptr = NULL; if (curptr == NULL) { /* handle new-list case and return */ *ptr = newptr; return; } if (value < curptr->data) { /* handle new 1st node */ newptr->nextptr = curptr; *ptr = newptr; return; } /* iterate with curptr until value > curptr->nextptr->data */ while (curptr->nextptr != NULL && value > curptr->nextptr->data) curptr = curptr->nextptr; newptr->nextptr = curptr->nextptr; /* wire new node to next node */ curptr->nextptr = newptr; /* wire current to new node */ 函数来为您处理。您可以编写类似以下内容的简单内容:

listfree

注意:在列表前进到下一个节点之前,如何将要释放的节点保存到临时指针void freelist (rec_t *head) { while (head) { rec_t *victim = head; head = head->nextptr; free (victim); } } 中。)

完全将其放入,您可以执行以下操作:

victim

使用/输出示例

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

typedef struct record {
    int data;
    struct record *nextptr;
} rec_t;

void insert (rec_t **ptr, int value);
void printList (rec_t *ptr);
void freelist (rec_t *head);

int main (void) {
    rec_t *headptr = NULL;

    for (int i = 0; i < 4; ++i) {
        int data;
        printf("Enter your value: ");
        scanf("%d", &data);
        insert (&headptr, data);
    }
    printList(headptr);
    freelist (headptr);

    return 0;
}

void insert (rec_t **ptr, int value) 
{
    if ( ptr == NULL ) {
        return;  
    } 

    rec_t *curptr = *ptr,
        *newptr = malloc (sizeof *newptr);  /* don't cast the return */
    if (!newptr) {
        perror ("malloc-newptr");
        return;
    }

    newptr->data = value;
    newptr->nextptr = NULL;

    if (curptr == NULL) {       /* handle new-list case and return */
        *ptr = newptr;
        return;
    }

    if (value < curptr->data) {     /* handle new 1st node */
        newptr->nextptr = curptr;
        *ptr = newptr;
        return;
    }

    /* iterate with curptr until value > curptr->nextptr->data */
    while (curptr->nextptr != NULL && value > curptr->nextptr->data)
        curptr = curptr->nextptr;

    newptr->nextptr = curptr->nextptr;      /* wire new node to next node */
    curptr->nextptr = newptr;               /* wire current to new node */
}

void printList(struct record *ptr)
{
    while (ptr != NULL) {
        printf(" %d", ptr->data);
        ptr = ptr->nextptr;
    }
    putchar ('\n');
}

void freelist (rec_t *head)
{
    while (head) {
        rec_t *victim = head;
        head = head->nextptr;
        free (victim);
    }
}

仔细研究一下,如果您有任何疑问,请告诉我。

答案 3 :(得分:0)

首先,如果要在程序意外终止之前冲洗打印件,请使用setbuf(stdout, NULL);

第二,就像其他人提到的那样,您正在访问NULL中的while (value >= (curptr->data))指针元素,这会导致崩溃。

第三,您的insertprint逻辑也是错误的。

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

struct record{
    int data;
    struct record *nextptr;
};

void insert (struct record **ptr,int value);
void printList(struct record *ptr);

int main() {
    setbuf(stdout, NULL);
    struct record *headptr = NULL;
    for (int i = 0; i < 4; ++i) {
        int data;
        printf("Enter your value");
        scanf("%d", &data);
        insert(&headptr, data);
    }
    printList(headptr);


    return 0;
}
void insert (struct record **head,int value){
    printf("WE ARE IN THE INSERT FUNCTION");
    struct record *newptr = (struct record *) malloc(sizeof(struct record));
    newptr->data=value;
    newptr->nextptr=NULL;
    struct record *curptr=*head;
    struct record *prevcurptr=NULL;

    while(curptr!=NULL && value >= (curptr->data)){
        prevcurptr=curptr;
        curptr=curptr->nextptr;
    }
    if (curptr==NULL){
        if (prevcurptr==NULL) {         
            *head=newptr;
        } else {
            newptr->nextptr=prevcurptr->nextptr;
            prevcurptr->nextptr=newptr;
        }
    }
    else{
        newptr->nextptr=curptr;
        if (prevcurptr==NULL)       
            *head=newptr;
        else
            prevcurptr->nextptr=newptr;
    }

}
void printList(struct record *ptr){
    while(ptr != NULL){
        printf("\n %d", ptr->data);
        ptr=ptr->nextptr;
    }
}