C语言中的动态堆栈[弹出崩溃]

C语言中的动态堆栈[弹出崩溃],c,dynamic,stack,C,Dynamic,Stack,我正在制作一个程序,使用动态堆栈将十进制整数转换为二进制。 它在最后一次爆炸时崩溃了。 例数:4输出:10 #include <stdio.h> struct stack { struct stack *prev; int val; struct stack *next; }; struct stack *first,*cur,*tmp; struct stack *GETNODE(){ struct stack *pt = (struct stac

我正在制作一个程序,使用动态堆栈将十进制整数转换为二进制。 它在最后一次爆炸时崩溃了。 例数:4输出:10

#include <stdio.h>

struct stack {
    struct stack *prev;
    int val;
    struct stack *next;
};
struct stack *first,*cur,*tmp;
struct stack *GETNODE(){
    struct stack *pt = (struct stack *)malloc(sizeof(struct stack));
};
int counter=1;
void push(int val){
    tmp=GETNODE();
    tmp->prev=NULL;
    tmp->val=val;
    tmp->next=NULL;
    if(first==NULL){
        first=tmp;
        cur=first;
    }else{
        tmp->prev=cur;
        cur->next=tmp;
        cur=tmp;
    }
    counter++;
};

int pop(){
    int val=tmp->val;
    cur=tmp->prev;
    free(tmp);
    tmp=cur;
    tmp->next=NULL;
    counter--;
    return(val);
};


main(){
    int num = 4;
    while(num!=0){
        push(num%2);
        num/=2;
    }
    while(counter!=1){
        printf("%d ",pop());
    }
}
#包括
结构堆栈{
结构堆栈*prev;
int-val;
结构堆栈*下一步;
};
结构堆栈*first、*cur、*tmp;
结构堆栈*GETNODE(){
结构堆栈*pt=(结构堆栈*)malloc(sizeof(结构堆栈));
};
int计数器=1;
无效推送(int val){
tmp=GETNODE();
tmp->prev=NULL;
tmp->val=val;
tmp->next=NULL;
if(first==NULL){
第一个=tmp;
cur=第一;
}否则{
tmp->prev=cur;
cur->next=tmp;
cur=tmp;
}
计数器++;
};
int-pop(){
int val=tmp->val;
cur=tmp->prev;
免费(tmp);
tmp=cur;
tmp->next=NULL;
计数器--;
返回(val);
};
main(){
int num=4;
while(num!=0){
推送(数量%2);
num/=2;
}
while(计数器!=1){
printf(“%d”,pop());
}
}

问题出在pop函数中。如果你想一想它是如何运作的,在最后的关卡中你将获得自由(tmp),它目前指向第一个项目。释放后,您可以指定:

tmp->next=NULL;

此时您正在尝试取消引用无效指针。

我对您的代码做了很多更改。主要是,它太复杂了——只需要一个单链表,而不需要计数器——只需跟踪列表指针即可。
GETNODE()
函数未返回值,导致调用函数中出现未定义的行为。我也简化了这一点,不需要单独的函数来分配内存,因为
malloc()
已经这样做了

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

struct stack {
    struct stack *prev;
    int val;
};

struct stack *first = NULL;

void push(int val){
    struct stack *pt = malloc(sizeof(struct stack));
    if (pt == NULL){
        printf ("Bad call to malloc()\n");
        exit (1);
    }
    pt->prev=first;
    pt->val=val;
    first = pt;
}

int pop(){
    int val;
    struct stack *pt = first;
    if (first == NULL)
        return -1;
    val=first->val;
    first = first->prev;
    free(pt);
    return(val);
}

void dec2bin(int num){
    printf("%-5d", num);
    while(num!=0){
        push(num%2);
        num/=2;
    }
    while(first){
        printf("%d",pop());
    }
    printf("\n");
}

int main(void){
    dec2bin (4);
    dec2bin (129);
    dec2bin (160);
    return 0;
}

我更改了你的部分代码,你的代码现在可以工作了

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

struct stack {
     struct stack *prev;
     int val;
     struct stack *next;
};

struct stack *first, *cur, *tmp;
int counter = 0;

struct stack *GETNODE()
{
     return malloc(sizeof(struct stack));
}


void push(int val)
{
    tmp = GETNODE();
    tmp->prev = NULL;
    tmp->val = val;
    tmp->next = NULL;

    if (first == NULL) {
         first = tmp;
         cur = first;
    } else {
         tmp->prev = cur;
         cur->next = tmp;
         cur = tmp;
    }
    counter++;
}

int pop(void)
{
     int val = cur->val;

     tmp = cur;
     cur = cur->prev;
     free(tmp);
     counter--;

     return val;
 }


int main(int argc, char *argv[])
{
    int num;

    scanf("%d", &num);

    while (num != 0) {
        push(num % 2);
        num /= 2;
    }
    while (counter != 0)
    printf("%d ", pop());
    printf("\n");
}
#包括
#包括
结构堆栈{
结构堆栈*prev;
int-val;
结构堆栈*下一步;
};
结构堆栈*first、*cur、*tmp;
int计数器=0;
结构堆栈*GETNODE()
{
返回malloc(sizeof(struct stack));
}
无效推送(int val)
{
tmp=GETNODE();
tmp->prev=NULL;
tmp->val=val;
tmp->next=NULL;
if(first==NULL){
第一个=tmp;
cur=第一;
}否则{
tmp->prev=cur;
cur->next=tmp;
cur=tmp;
}
计数器++;
}
int-pop(无效)
{
int val=cur->val;
tmp=cur;
cur=cur->prev;
免费(tmp);
计数器--;
返回val;
}
int main(int argc,char*argv[])
{
int-num;
scanf(“%d”和&num);
while(num!=0){
推送(数量%2);
num/=2;
}
while(计数器!=0)
printf(“%d”,pop());
printf(“\n”);
}

MSVC编译器警告C4716:
'GETNODE':必须返回一个值。
@JonathonReinhart这就是老师告诉我们的方法,而且这似乎不是问题。请告诉你的老师也要
#包含
。如果你的老师真的认为强制转换可以代替正确的声明,你需要一个新老师。告诉他们,哇,谢谢!我永远不会注意到,如果您使用调试器遍历代码,您会注意到它。
 #include <stdio.h>
 #include <stdlib.h>

struct stack {
     struct stack *prev;
     int val;
     struct stack *next;
};

struct stack *first, *cur, *tmp;
int counter = 0;

struct stack *GETNODE()
{
     return malloc(sizeof(struct stack));
}


void push(int val)
{
    tmp = GETNODE();
    tmp->prev = NULL;
    tmp->val = val;
    tmp->next = NULL;

    if (first == NULL) {
         first = tmp;
         cur = first;
    } else {
         tmp->prev = cur;
         cur->next = tmp;
         cur = tmp;
    }
    counter++;
}

int pop(void)
{
     int val = cur->val;

     tmp = cur;
     cur = cur->prev;
     free(tmp);
     counter--;

     return val;
 }


int main(int argc, char *argv[])
{
    int num;

    scanf("%d", &num);

    while (num != 0) {
        push(num % 2);
        num /= 2;
    }
    while (counter != 0)
    printf("%d ", pop());
    printf("\n");
}