代码之家  ›  专栏  ›  技术社区  ›  Gameatro

为什么malloc在函数内部调用时返回空指针?

  •  1
  • Gameatro  · 技术社区  · 8 年前

    我做了一个代码 malloc() 调用,但它返回空指针。当我打电话时 malloc() 在里面 main() 并传递到函数,它工作得非常好。所以请告诉我问题出在哪里。

    这是我的密码。我对 malloc() 在函数中 reverse() 这个 malloc() 其他功能中的s工作正常。那个么为什么那个函数中的一个有问题呢。我的电脑有足够的内存,所以这绝对不是问题所在。

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct node
    {
        int data;
        struct node *next;
    } SNode;
    
    
    typedef struct
    {
        int count;
        SNode *top;
    } Stack;
    
    int isSEmpty(Stack *s)
    {
        return (s->count==0);
    }
    
    void push(Stack *s, int x)
    {
        SNode *temp = (SNode *)malloc(sizeof(SNode));
        temp->data = x;
        temp->next = s->top;
        s->top = temp;
        s->count++;
    }
    
    int pop(Stack *s)
    {
        if (isSEmpty(s))
        {
            printf("Underflow");
            return -1;
        }
        SNode *temp = s->top;
        s->top = s->top->next;
        int t = temp->data;
        free(temp);
        s->count--;
        return t;
    }
    typedef struct qnode
    {
        int data;
        struct qnode *next, *prev;
    } QNode;
    
    typedef struct
    {
        QNode *front, *rear;
        int count;
    } Queue;
    
    int isQEmpty(Queue *q)
    {
        return (q->count==0);
    }
    
    void enQueue(Queue *q, int x)
    {
        QNode *temp = (QNode *)malloc(sizeof(QNode));
        temp->data = x;
        temp->prev=q->rear;
        temp->next = NULL;
        q->rear->next = temp;
        q->rear = temp;
        q->count++;
        if (q->count==1)
        {
            q->front = q->rear;
        }
    }
    
    int deQueue(Queue *q)
    {
        if (isQEmpty(q))
        {
            printf("Underflow");
            return -1;
        }
        QNode *temp = q->front;
        q->front = q->front->next;
        int t = temp->data;
        free(temp);
        q->count--;
        return t;
    }
    void reverse(Queue *q)
    {
        Stack *s = (Stack *)malloc(sizeof(Stack));
        s->count = 0;
    
        while (!isQEmpty(q))
        {
            push(s, deQueue(q));
        }
        while (!isSEmpty(s))
        {
            enQueue(q, pop(s));
        }
    }
    
    int main()
    {
        char p = 'y';
        Queue *q = (Queue *)malloc(sizeof(Queue));
    
        q->count = 0;
        while (p =='y')
        {
            printf("Enter data to be Enqueued: ");
            int d;
            scanf("%d", &d);
            enQueue(q, d);
            printf("Do you want to enter more data? y/n:");
            scanf(" %c", &p);
        }
        printf("Original queue Front: %d Rear: %d\n", q->front->data, q->rear->data);
        reverse(q);
        printf("Reversed queue Front: %d Rear: %d", q->front->data, q->rear->data);
        return 0;
    }
    
    2 回复  |  直到 8 年前
        1
  •  5
  •   Iharob Al Asimi    8 年前

    您的程序几乎没有内存不足,这就是为什么 malloc() 将返回 NULL 。相反,糟糕的编程风格和凌乱的代码的结合,导致了与访问未初始化内存相关的问题 未定义的行为 ,一旦触发UB,就无法再预测程序的行为。

    首先要解决的是避免这种构造

    q->rear->next = temp;
    

    因为 q->rear 可能是 无效的 因此,如果取消引用UB,则会调用它。

    然后需要显式初始化结构的成员, malloc() 只有 分配 内存供您使用,它不进行任何初始化,一个好的方法是创建一个分配和初始化空实例的函数,如下所示

    Queue *queue_new(int count) 
    {
        Queue *queue;
        queue = malloc(sizeof(*queue));
        if (queue == NULL)
            return NULL;
        queue->count = count;
        queue->front = NULL;
        queue->rear = NULL;
        return queue;
    }
    

    此外,不要将声明与代码混用。我必须寻找 Queue 我使用代码编辑器的查找/替换功能编写了上述函数。

    将所有结构和类型定义放在所有代码之上,以便于查找其中任何一个。

        2
  •  3
  •   Michael Burr    8 年前

    您没有初始化 *q 在'main()中初始化分配的结构:

    Queue *q = (Queue *)malloc(sizeof(Queue));
    
    q->count = 0;
    

    然后你传过去 q 指向的指针 enQueue() 并做以下事情:

    q->rear->next = temp;
    

    我想你也可以用 q->front 没有初始化它。

    这些都是未定义的行为,在您的情况下,可能会损坏堆,导致 malloc() 不要像你期望的那样工作。如果您正在使用Linux,valgrind可能会很有用。

    推荐文章