试图抵消用C的指针,当段错误 [英] Segfault when attempting to nullify a pointer in C

查看:95
本文介绍了试图抵消用C的指针,当段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以现在我想实现一个deltaclock,那我想第一个步骤是先它采用了双链表优先级队列(我将在后面做其他的东西deltaclock)。被从优先级队列中弹出所述第一元素是一个是在链表的根(或deltaClock结构)。

我推了几个元素到队列在我的测试,经过了几个流行的操作,还有在它时,它从近空列表弹出出现segfaults一个案例。

当我注释掉,在弹出方法,其中我说:顺时针>根 - > previous = 0;行了,当我流行过的元素在main方法的程序不段错误。但是,必须摆脱了自previous节点将不再存在指针previous节点。

我怎样才能让这个新的根的previous指针将是无效的,当我执行弹出操作?

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;结构deltaNode {
    诠释抽动; // 资源
    结构deltaNode *接下来的;
    结构deltaNode * previous;
};结构deltaClock {
    结构deltaNode *根;
    结构deltaNode *尾;
    INT大小;
};无效initDeltaClock(结构deltaClock **时钟){
    (*时钟)=的ma​​lloc(sizeof的(结构deltaClock));
    (*时钟) - GT;大小= 0;
}空推(结构deltaClock *时钟,诠释numberOfTics){
如果(时钟>根== 0){
    //根是空的,对其进行初始化。
    时钟 - >根=的malloc(sizeof的(结构deltaNode));
    时钟 - >&根 - GT;抽动= numberOfTics;
    时钟 - >尾=顺时针>根;
}
其他{
    结构deltaNode * newNode =的malloc(sizeof的(结构deltaNode));
    newNode->抽动= numberOfTics;
    结构deltaNode * TEMP =顺时针>根;    如果(newNode->&抽动LT; TEMP-GT&;抽动){
        时钟 - >&根 - GT; previous = newNode;
        newNode->接下来=顺时针>根;
        时钟 - >根= newNode;
    }其他{
        而(newNode->&抽动GT; TEMP-GT&;抽动){
            如果(TEMP->接着== 0){
                打破;
            }
            TEMP = TEMP->接下来,
        }        如果(TEMP->接着== 0&放大器;&放大器; newNode->抽动> TEMP-&G​​T;抽搐){
            时钟 - > tail->接下来= newNode;
            newNode-> previous =顺时针>尾;
            时钟 - >尾= newNode;
        }
        其他{
            TEMP-GT&; previous->接下来= newNode;
            newNode-> previous = TEMP-GT&; previous;
            newNode->接下来=温度;
            TEMP-GT&; previous = newNode;
        }    }}
时钟 - >大小++;
}INT流行(结构deltaClock *时钟){
    结构deltaNode * TEMP =顺时针>根;
       如果(温度== 0){
        返回-1;
    }
    INT结果= TEMP-GT&;抽动;
    时钟 - >根顺时针=>根 - >接下来,
    时钟 - >&根 - GT; previous = 0;
    免费(TEMP);
    时钟 - > size--;
    返回结果;
}无效printClock(结构deltaClock *时钟){
    结构deltaNode *迭代器;
    迭代器=顺时针>根;
    而(迭代器!= 0){
            的printf(\\ N%D,iterator->抽动);
            迭代器= iterator->接下来,
    }
}
INT主(INT ARGC,CHAR *的argv []){
    的printf(\\ nHello世界。);
    结构deltaClock *时钟;
    initDeltaClock(安培;时钟);
    推(时钟,3);
    推(时钟,2);
    推(时钟,7);
    推(时钟,33);
    推(时钟,221);
    推(时钟,5);
    printClock(时钟);
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ npopping%D,弹出(时钟));
    推(时钟,25);
    的printf(\\ npopping%D,弹出(时钟));
    的printf(\\ n);
}


解决方案

有关它的价值,这code运行合理的三立:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;结构deltaNode
{
    诠释抽动; // 资源
    结构deltaNode *接下来的;
    结构deltaNode * previous;
};结构deltaClock
{
    结构deltaNode *根;
    结构deltaNode *尾;
    INT大小;
};无效initDeltaClock(结构deltaClock *时钟);无效initDeltaClock(结构deltaClock *时钟)
{
    (*时钟)=的ma​​lloc(sizeof的(结构deltaClock));
    (*时钟) - GT;大小= 0;
}空推(结构deltaClock *时钟,诠释numberOfTics);空推(结构deltaClock *时钟,诠释numberOfTics)
{
    如果(时钟>根== 0)
    {
        //根是空的,对其进行初始化。
        时钟 - >根=的malloc(sizeof的(结构deltaNode));
        时钟 - >&根 - GT;抽动= numberOfTics;
        时钟 - >尾=顺时针>根;
    }
    其他
    {
        结构deltaNode * newNode =的malloc(sizeof的(结构deltaNode));
        newNode->抽动= numberOfTics;
        结构deltaNode * TEMP =顺时针>根;        如果(newNode->&抽动LT; TEMP-GT&;抽动)
        {
            时钟 - >&根 - GT; previous = newNode;
            newNode->接下来=顺时针>根;
            时钟 - >根= newNode;
        }
        其他
        {
            而(newNode->&抽动GT; TEMP-GT&;抽动)
            {
                如果(TEMP->接着== 0)
                    打破;
                TEMP = TEMP->接下来,
            }            如果(TEMP->接着== 0&放大器;&放大器; newNode->抽动> TEMP-&G​​T;抽搐)
            {
                时钟 - > tail->接下来= newNode;
                newNode-> previous =顺时针>尾;
                时钟 - >尾= newNode;
            }
            其他
            {
                TEMP-GT&; previous->接下来= newNode;
                newNode-> previous = TEMP-GT&; previous;
                newNode->接下来=温度;
                TEMP-GT&; previous = newNode;
            }
        }
    }
    时钟 - >大小++;
}INT流行(结构deltaClock *时钟);INT流行(结构deltaClock *时钟)
{
    结构deltaNode * TEMP =顺时针>根;
    如果(临时== 0)
        返回-1;
    INT结果= TEMP-GT&;抽动;
    时钟 - >根顺时针=>根 - >接下来,
    如果(时钟>根!= 0)
        时钟 - >&根 - GT; previous = 0;
    免费(TEMP);
    时钟 - > size--;
    返回结果;
}无效printClock(结构deltaClock *时钟);无效printClock(结构deltaClock *时钟)
{
    结构deltaNode *迭代器;
    迭代器=顺时针>根;
    而(迭代器!= 0)
    {
        的printf(%d个,iterator->抽动);
        迭代器= iterator->接下来,
    }
    的putchar('\\ n');
}INT主要(无效)
{
    的printf(世界,你好\\ n);
    结构deltaClock *时钟;
    initDeltaClock(安培;时钟);
    推(时钟,3);
    推(时钟,2);
    推(时钟,7);
    推(时钟,33);
    推(时钟,221);
    推(时钟,5);
    printClock(时钟);
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(啪%d个\\ N,弹出(时钟));
    推(时钟,25);
    的printf(啪%d个\\ N,弹出(时钟));
    的printf(\\ n);
}

它产生:

 世界,你好。
 2 3 5 7 33 221
啪2
3弹出
5弹出
啪7
啪33
弹出221
啪-1
啪-1
啪-1
啪-1
啪-1
啪-1
啪25

主要的变化不是设置顺时针>根 - > previous = 0; 除非顺时针>根不为null。

次要的变化所添加的新行的打印语句的末尾,从一开始就去除它们。而名单水平打印,每行多个号码,而不是每行一个数字。

中显示的code编译使用干净:

  GCC -O3 -g -std = C11 -Wall -Wextra -Wmissing的原型-Wstrict的原型\\
    -WOLD式高清pl.c -o PL

需要的函数声明与这些选项编译干净;他们一般是一个好主意。另一种方法是让所有的功能静态的,这也适用于单个文件的程序。使code编译干净所需的唯一变化是加入函数原型和替换主(INT ARGC,字符** argv的)主要(无效) - 做得好,这是不寻常的好

So right now I'm trying to implement a deltaclock, and the first step that I'm trying is to first make a priority queue which uses a double-linked list (I will do the other deltaclock stuff later). The first element to be popped from the priority queue is the one that is at the root of the linked list (or the deltaClock struct).

I push a few elements onto the queue in my test, and after a few pop operations, there is one case in which it segfaults when it's popping from a nearly empty list.

When I comment out the line in the pop method where I say "clock->root->previous = 0;", the program in the main method does not segfault when I pop off elements. However, the pointer to the previous node needs to be gotten rid of since the previous node will not exist anymore.

How can I make it so that the new root's previous pointer will be null when I perform the pop operation?

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

struct deltaNode{
    int tics;                  // source
    struct deltaNode* next;
    struct deltaNode* previous;
};

struct deltaClock{
    struct deltaNode* root;
    struct deltaNode* tail;
    int size;
};

void initDeltaClock(struct deltaClock **clock){
    (*clock) = malloc(sizeof(struct deltaClock));
    (*clock)->size = 0;
}

void push(struct deltaClock* clock, int numberOfTics){
if(clock->root == 0){
    // root is empty, initialize it.
    clock->root = malloc(sizeof(struct deltaNode));
    clock->root->tics = numberOfTics;
    clock->tail = clock->root;
} 
else {
    struct deltaNode* newNode = malloc(sizeof(struct deltaNode));
    newNode->tics = numberOfTics;
    struct deltaNode* temp = clock->root;

    if(newNode->tics < temp->tics){
        clock->root->previous = newNode;
        newNode->next = clock->root;
        clock->root = newNode;
    } else {
        while(newNode->tics > temp->tics){
            if(temp->next == 0){
                break;
            }
            temp = temp->next;
        }

        if(temp->next == 0 && newNode->tics > temp->tics){
            clock->tail->next = newNode;
            newNode->previous = clock->tail;
            clock->tail = newNode;
        }
        else{
            temp->previous->next = newNode;
            newNode->previous = temp->previous;
            newNode->next = temp;
            temp->previous = newNode;
        }

    }

}
clock->size++;
}

int pop(struct deltaClock* clock){
    struct deltaNode* temp = clock->root;
       if(temp == 0){
        return -1;
    }
    int result = temp->tics;
    clock->root = clock->root->next;
    clock->root->previous = 0;
    free(temp);
    clock->size--;
    return result;
}

void printClock(struct deltaClock* clock){
    struct deltaNode* iterator;
    iterator = clock->root;
    while(iterator != 0){
            printf("\n%d",iterator->tics);
            iterator = iterator->next;
    }
}


int main(int argc, char* argv[]){
    printf("\nHello world.");
    struct deltaClock* clock;
    initDeltaClock(&clock);
    push(clock, 3);
    push(clock, 2);
    push(clock, 7);
    push(clock, 33);
    push(clock, 221);
    push(clock, 5);
    printClock(clock);
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    printf("\npopping %d",pop(clock));
    push(clock, 25);
    printf("\npopping %d",pop(clock));
    printf("\n");
}

解决方案

For what it's worth, this code runs reasonably sanely:

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

struct deltaNode
{
    int tics;                  // source
    struct deltaNode *next;
    struct deltaNode *previous;
};

struct deltaClock
{
    struct deltaNode *root;
    struct deltaNode *tail;
    int size;
};

void initDeltaClock(struct deltaClock * *clock);

void initDeltaClock(struct deltaClock * *clock)
{
    (*clock) = malloc(sizeof(struct deltaClock));
    (*clock)->size = 0;
}

void push(struct deltaClock *clock, int numberOfTics);

void push(struct deltaClock *clock, int numberOfTics)
{
    if (clock->root == 0)
    {
        // root is empty, initialize it.
        clock->root = malloc(sizeof(struct deltaNode));
        clock->root->tics = numberOfTics;
        clock->tail = clock->root;
    }
    else
    {
        struct deltaNode *newNode = malloc(sizeof(struct deltaNode));
        newNode->tics = numberOfTics;
        struct deltaNode *temp = clock->root;

        if (newNode->tics < temp->tics)
        {
            clock->root->previous = newNode;
            newNode->next = clock->root;
            clock->root = newNode;
        }
        else
        {
            while (newNode->tics > temp->tics)
            {
                if (temp->next == 0)
                    break;
                temp = temp->next;
            }

            if (temp->next == 0 && newNode->tics > temp->tics)
            {
                clock->tail->next = newNode;
                newNode->previous = clock->tail;
                clock->tail = newNode;
            }
            else
            {
                temp->previous->next = newNode;
                newNode->previous = temp->previous;
                newNode->next = temp;
                temp->previous = newNode;
            }
        }
    }
    clock->size++;
}

int pop(struct deltaClock *clock);

int pop(struct deltaClock *clock)
{
    struct deltaNode *temp = clock->root;
    if (temp == 0)
        return -1;
    int result = temp->tics;
    clock->root = clock->root->next;
    if (clock->root != 0)
        clock->root->previous = 0;
    free(temp);
    clock->size--;
    return result;
}

void printClock(struct deltaClock *clock);

void printClock(struct deltaClock *clock)
{
    struct deltaNode *iterator;
    iterator = clock->root;
    while (iterator != 0)
    {
        printf(" %d", iterator->tics);
        iterator = iterator->next;
    }
    putchar('\n');
}

int main(void)
{
    printf("Hello world.\n");
    struct deltaClock *clock;
    initDeltaClock(&clock);
    push(clock, 3);
    push(clock, 2);
    push(clock, 7);
    push(clock, 33);
    push(clock, 221);
    push(clock, 5);
    printClock(clock);
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    printf("popping %d\n", pop(clock));
    push(clock, 25);
    printf("popping %d\n", pop(clock));
    printf("\n");
}

It produces:

Hello world.
 2 3 5 7 33 221
popping 2
popping 3
popping 5
popping 7
popping 33
popping 221
popping -1
popping -1
popping -1
popping -1
popping -1
popping -1
popping 25

The primary change is not setting clock->root->previous = 0; unless clock->root is not null.

Secondary changes are adding newlines to the end of the print statements, and removing them from the beginning. And the list is printed horizontally, multiple numbers per line, rather than one number per line.

The code shown compiles cleanly using:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition pl.c -o pl

The function declarations are needed to compile cleanly with those options; they're a good idea in general. The alternative is to make the functions all static, which also works for single-file programs. The only changes needed to make the code compile cleanly were adding the function prototypes and replacing main(int argc, char **argv) with main(void) — well done, that's unusually good.

这篇关于试图抵消用C的指针,当段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆