无法访问结构中字符数组的内存错误 - C

Cannot access memory error for character array in struct - C

我正在尝试使用 C 中的链表创建队列。我使用两个结构来表示队列和每个节点,如下所示。

#define DATA_MAX 100

struct QueueNode_ch 
{
    struct QueueNode_ch* next;
    char data[(DATA_MAX + 1)];
};
typedef struct QueueNode_ch QueueNode_ch;

struct Queue_ch
{
    struct QueueNode_ch* front;
    struct QueueNode_ch* rear;
    int count;
};
typedef struct Queue_ch Queue_ch;

然后我使用以下这些函数来初始化队列和节点。

int initQueue_ch(Queue_ch* q)
{
    q = (Queue_ch*)malloc(sizeof(Queue_ch));
    q->count = 0;
    q->front = NULL;
    q->rear = NULL;
    return 0;
}

int initQueueNode_ch(QueueNode_ch* node)
{
    node = (QueueNode_ch*)malloc(sizeof(QueueNode_ch));
    node->next = NULL;
    node->data[0] = '[=11=]';
    return 0;
}

在 运行 我的入队函数上,由于 strcpy 函数,我遇到了一个段错误,并且在调试 gdb 时说它无法访问我试图添加的节点的内存。入队代码如下:

int enqueue_ch(Queue_ch* q, char* data)
{
    if(strlen(data) > (DATA_MAX + 1))
        return 1;
    QueueNode_ch* tmp;
    initQueueNode_ch(tmp);
    strncpy(tmp->data, data, DATA_MAX);
    if(isEmpty_queue_ch(q))
        q->rear = q->front = tmp;
    else
    {
        q->rear->next = tmp;
        q->rear = tmp;
    }
    q->count++;
    return 0;
}

我还将包括我的主要功能作为附加信息。

#include <stdio.h>
#include "Queue.h"

int main()
{
    Queue_ch* queue;
    initQueue_ch(queue);
    enqueue_ch(queue, "hello");
    return 0;
}

据我所知,应该有很多 space 可以将给定的字符串复制到节点。有谁知道失败的原因和可能的修复方法吗?

int initQueue_ch(Queue_ch* q)
{
    q = (Queue_ch*)malloc(sizeof(Queue_ch));
    q->count = 0;
    q->front = NULL;
    q->rear = NULL;
    return 0;
}

此功能无法使用。它忽略传递给它的 q 的值,并且不会 return 指向它初始化的队列的指针。 C严格按值传递。

int main()
{
    Queue_ch* queue;
    initQueue_ch(queue);
    enqueue_ch(queue, "hello");
    return 0;
}

此代码从不给 queue 任何值,并将垃圾值传递给 initQueue_ch(它忽略),然后将垃圾值传递给 enqueue_ch

正如其他人所提到的,您正在按值传递结构。在 C 语言中,正确的做法是使用指向指针的指针。请注意,我还没有尝试编译它,但希望这个想法很清楚。

int initQueue_ch(Queue_ch** q)
{
    *q = (Queue_ch*)malloc(sizeof(Queue_ch));
    (*q)->count = 0;
    (*q)->front = NULL;
    (*q)->rear = NULL;
    return 0;
}

int initQueueNode_ch(QueueNode_ch** node)
{
    *node = (QueueNode_ch*)malloc(sizeof(QueueNode_ch));
    (*node)->next = NULL;
    (*node)->data[0] = '[=10=]';
    return 0;
}

函数initQueue_ch没有意义。

int initQueue_ch(Queue_ch* q)
{
    q = (Queue_ch*)malloc(sizeof(Queue_ch));
    q->count = 0;
    q->front = NULL;
    q->rear = NULL;
    return 0;
}

函数参数q是函数的局部变量。在函数内更改变量不会影响提供给函数的参数。

此外,动态分配队列也没有意义。该函数可以如下所示

void initQueue_ch( Queue_ch *q )
{
    q->count = 0;
    q->front = NULL;
    q->rear  = NULL;
}

主要你可以写

Queue_ch queue;
initQueue_ch( &queue );

函数initQueueNode_ch

也存在同样的问题
int initQueueNode_ch(QueueNode_ch* node)
{
    node = (QueueNode_ch*)malloc(sizeof(QueueNode_ch));
    node->next = NULL;
    node->data[0] = '[=13=]';
    return 0;
}

该函数再次处理传递参数值的副本。更改副本不会影响原始参数。

功能整体上没有意义。你需要的是一个分配新节点的函数。

例如可以通过以下方式查找

QueueNode_ch * createQueueNode_ch( const char *data )
{
    QueueNode_ch *node = malloc( sizeof( QueueNode_ch ) );

    if ( node != NULL )
    {
        node->next = NULL;
        strcpy( node->data, data );
    }

    return node;
}

具有按值将指针传递给队列的相同缺点的函数 enqueue_ch 可能看起来像

int enqueue_ch( Queue_ch *q, const char *data )
{
    int success = strlen( data ) < DATA_MAX + 1;

    if ( success )
    {
        QueueNode_ch *node = createQueueNode_ch( data );

        success = node != NULL;

        if ( success )
        {
            if ( q->rear == NULL )
            {
                q->front = q->rear = node;
            }
            else
            {
                q->rear = q->rear->next = node;
            }

            ++q->count;
        }
    }

    return success;
}

这是一个演示程序。

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

#define DATA_MAX 100

struct QueueNode_ch 
{
    struct QueueNode_ch* next;
    char data[(DATA_MAX + 1)];
};
typedef struct QueueNode_ch QueueNode_ch;

struct Queue_ch
{
    struct QueueNode_ch* front;
    struct QueueNode_ch* rear;
    int count;
};
typedef struct Queue_ch Queue_ch;

void initQueue_ch( Queue_ch *q )
{
    q->count = 0;
    q->front = NULL;
    q->rear  = NULL;
}

QueueNode_ch * createQueueNode_ch( const char *data )
{
    QueueNode_ch *node = malloc( sizeof( QueueNode_ch ) );

    if ( node != NULL )
    {
        node->next = NULL;
        strcpy( node->data, data );
    }

    return node;
}

int enqueue_ch( Queue_ch *q, const char *data )
{
    int success = strlen( data ) < DATA_MAX + 1;

    if ( success )
    {
        QueueNode_ch *node = createQueueNode_ch( data );

        success = node != NULL;

        if ( success )
        {
            if ( q->rear == NULL )
            {
                q->front = q->rear = node;
            }
            else
            {
                q->rear = q->rear->next = node;
            }

            ++q->count;
        }
    }

    return success;
}

void deleteQueue_ch( Queue_ch *q )
{
    while ( q->front != NULL )
    {
        QueueNode_ch *node = q->front;
        q->front = q->front->next;
        free( node );
    }

    q->rear = q->front;
    q->count = 0;
}

int main(void) 
{
    Queue_ch queue;
    initQueue_ch( &queue );

    enqueue_ch( &queue, "hello" );

    deleteQueue_ch( &queue );

    return 0;
}

如果您使用 malloc() 进行初始化,那么 return pointer() 而不是像下面那样将指针传递给函数。

struct wordlist* wordlist_create(void)
{
    struct wordlist* wordListPtr = (struct wordlist*) malloc(sizeof(struct wordlist));
    wordListPtr->count = 0;

    wordListPtr->root = getTrieNode();

    return wordListPtr;
}