我是个新手,需要一些大学作业(job)代码的帮助. 我正在try 用C语言编写将 node 插入到列表末尾的代码,但创建新 node 的操作不起作用.

首先,这是我在作业(job)中收到的代码:

typedef struct listNode {
    int* dataPtr;
    struct listNode* next;
}ListNode;

typedef struct list
{
    ListNode* head;
    ListNode* tail;
}List;

并且:

List getList()
{
    List res;
    int size, num, i;
    makeEmptyList(&res);
    printf("Please enter the number of items to be entered:\n");
    scanf("%d", &size);
    printf("Please enter the numbers:\n");
    for(i = 0; i < size; i++)
    {
        scanf("%d", &num);
        insertDataToEndList(&res, num);
    }
    return res;
}

void main()
{
    List lst1, lst2, mergedList;
    lst1 = getList();
    lst2 = getList();
    mergedList = merge(lst1,lst2);
    printf("Merged list:\n");
    printList(&mergedList);

    freeList(&lst1);
    freeList(&lst2);
    freeList(&mergedList);
}

下面是我try 编写的insertDataToEndList个代码:

// Add Node to end list

void insertDataToEndList(List* lst, int data)
{
    ListNode* newTail;
    newTail = createNewListNode(&data, NULL);
    insertNodeToEndList(lst, newTail);
}
ListNode* createNewListNode(int* data, ListNode* next)
{
    ListNode* res;
    res = (ListNode*)malloc(sizeof(ListNode));
    res->dataPtr = data;
    res->next = next;
    return res;
}

void insertNodeToEndList(List* lst, ListNode* tail)
{
    if (isEmptyList(lst) == true)
        lst->head = lst->tail = tail;
    else
    {
        lst->tail->next = tail;
        lst->tail = tail;
    }
    tail->next = NULL;
}

问题是,当我打印已经输入的两个列表时,打印值根本不是我输入的值.

推荐答案

由于insertDataToEndList函数的data参数是在堆栈上分配的,因此一旦该函数返回,其地址就不再引用分配的内存.然而,您已将此地址保存在res->dataPtr = data;号.当您读取dataPtr指向的内存时(例如,稍后打印该列表或执行合并时),这将导致未定义的行为.

所以不要用&data.相反,使用此调用将data传递到insertDataToEndList:

    newTail = createNewListNode(data, NULL);

然后更改insertDataToEndList以修复此错误:

ListNode* createNewListNode(int data, ListNode* next) // First param is int
{
    ListNode* res = malloc(sizeof(*res));
    res->dataPtr = malloc(sizeof(int)); // Allocate the memory for the int
    (*res->dataPtr) = data; // Copy the int
    res->next = next;
    return res;
}

其他一些 comments :

  • Don't cast what malloc returns

  • 不要将isEmpty(lst)的结果与true的结果进行比较.只需执行以下操作:

        if (isEmptyList(lst))
    
  • 确保在调用函数之前声明了它们.因此,除非已经声明了函数,否则应该将insertDataToEndList函数定义移到它所依赖的另外两个函数下面.

您收到的代码显示了几个糟糕的做法,并使人对您正在查看的课程material 的质量产生了怀疑.例如:

  • void main() is wrong,正如一条 comments 所说,它是"...an indication that you're using a textbook written by someone who doesn't know the C language very well.".
  • freeList函数接受List*参数,这表明应该释放分配给列表(不仅是它的 node )的内存,但这没有任何意义,因为main函数已将它们声明为List个变量,因此不应对列表本身调用free.如果所涉及的列表都分配在堆上,情况会更一致.
  • 在动态分配的内存中为一个int存储int个值是无用的,也是一个糟糕的决定.

C++相关问答推荐

获取二维数组的最大元素

如何避免使用相对路径包含在c中

为什么下面的递归基本情况在C中不起作用?

如何使用Python C API实现多线程程序?

当打印字符串时,为什么在c中没有使用常量限定符时我会收到警告?

如何在Visual Studio代码中关闭此函数名称显示功能?

使用GOTO从多个嵌套循环C继续

将fget()与strcMP()一起使用不是正确的比较

用C宏替换strncMP函数中的参数

使用错误的命令执行程序

如何有效地编写代码来判断两个元素数量相同的数组即使在不同的位置也具有相同的元素?

强制转换变量以在 struct 中蚕食

我在反转双向链表时遇到问题

仅从限制指针参数声明推断非混叠

如何在不更改格式说明符的情况下同时支持双精度和长双精度?

可以';t从A9G模块拨打电话

如何在C中计算包含递增和递减运算符的逻辑表达式?

当另一个指向 const 的指针观察到数据时,通过指针更改数据是否安全?

OpenGL 中的非渐变 colored颜色 变化

窗口消息处理函数以某种方式更改了应保持不变的 int 变量的值