簡體   English   中英

為什么在函數內部調用時malloc返回空指針?

[英]Why is malloc returning null pointer when called inside a function?

我編寫了一個調用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: %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;
}

您的程序幾乎不會耗盡內存,這就是為什么malloc()返回NULL 取而代之的是不良的編程風格和凌亂的代碼的組合,導致與未初始化的內存訪問相關的問題,這是未定義的行為 ,一旦觸發UB,您將無法再預測程序的行為。

您需要解決的第一件事就是避免這種構造

q->rear->next = temp;

因為q->rear可能為NULL ,因此如果取消引用UB,則會調用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的定義才能編寫上述函數,而我是使用代碼編輯器的find / replace功能來完成此操作的。

將所有結構和類型定義放在一起放在所有代碼之上,以便輕松查找其中任何一個。

您沒有初始化您在`main()中分配的*q結構的所有字段:

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

q->count = 0;

然后,將那個q指針傳遞給enQueue()並執行以下操作:

q->rear->next = temp;

我認為您也可以在未初始化的情況下使用q->front

這些都是未定義的行為,在您的情況下,這很可能破壞了堆,導致malloc()無法按預期工作。 如果您在Linux上工作,則valgrind可能會有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM