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

时间:2018-04-08 00:23:14

标签: c stack queue malloc

我创建了一个调用malloc()的代码,但它返回一个空指针。当我在malloc()中调用相同的main()并传递给函数时,它完全正常。请告诉我这是什么问题。

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

#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 个答案:

答案 0 :(得分:5)

您的程序内存不足,这就是malloc()将返回NULL的原因。相反,错误的编程风格和凌乱的代码的组合导致与未初始化的内存的访问相关的问题,这是未定义的行为,一旦你触发UB,你就无法预测程序的行为了。

你需要解决的第一件事是避免这种结构

q->rear->next = temp;

因为q->rear可能是NULL,因此如果您取消引用它,就会调用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的定义来编写上面的函数,我使用代码编辑器的查找/替换功能。

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

答案 1 :(得分:3)

您没有初始化您在`main()中初始化分配的*q结构的所有字段:

Queue *q = (Queue *)malloc(sizeof(Queue));

q->count = 0;

然后将q指针传递给enQueue()并执行以下操作:

q->rear->next = temp;

我认为你也可以在没有初始化的情况下使用q->front

这些是未定义的行为,在您的情况下可能会破坏堆,导致malloc()无法正常工作。如果您正在使用Linux,那么valgrind可能会很有用。