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



我做了一个调用malloc()的代码,但它返回了一个空指针。当我在main()中调用相同的malloc()并传递给函数时,它完全正常工作。所以请告诉我问题出在哪里。

这是我的代码。我在函数reverse()中的malloc()有问题。其他函数中的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: %dn", q->front->data, q->rear->data);
reverse(q);
printf("Reversed queue Front: %d Rear: %d", q->front->data, q->rear->data);
return 0;
}

您的程序几乎没有内存不足,这就是为什么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的定义来编写上述函数,并且我使用代码编辑器的查找/替换功能来实现。

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

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

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

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

q->rear->next = temp;

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

这些事情是未定义的行为,在您的情况下可能会损坏堆,导致malloc()无法按预期工作。 如果你正在开发Linux,valgrind可能会很有用。

最新更新