错误:从 'void*' 到 'node_t*' 的无效转换 [关闭]

Posted

技术标签:

【中文标题】错误:从 \'void*\' 到 \'node_t*\' 的无效转换 [关闭]【英文标题】:error: invalid conversion from 'void*' to 'node_t*' [closed]错误:从 'void*' 到 'node_t*' 的无效转换 [关闭] 【发布时间】:2021-05-14 08:06:30 【问题描述】:

每当我尝试运行下面的代码时,我都会在第 34 行收到以下错误:

错误:从 'void*' 到 'node_t*' 的无效转换

我是指针和链表的新手,我正在看一个关于如何使用它们的教程(这个:Understanding and implementing a Linked List in C and Java),我复制了大部分内容,就像视频中显示的一样,但它仍然不工作。

我该如何解决?

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <math.h>
#include <iostream>
using namespace std;

typedef struct node 
   int value;
   struct node *next;
 node_t;

void printlist(node_t *head)
    node_t *temporary = head;
    while(temporary != NULL)
        cout << temporary -> value << endl;
        temporary = temporary -> next;
    
    cout << endl;

node_t *create_new_node(int value)
    node_t *result = malloc(sizeof(node_t));   // <----- line 34
    result->value = value;
    result->next = NULL;
    return result;


int main()

    setlocale(LC_ALL, "portuguese");

    node_t *head;
    node_t *tmp;
    tmp = create_new_node(32);
    head = tmp;
    tmp = create_new_node(8);
    tmp->next = head;
    head = tmp;
    tmp = create_new_node(34);
    tmp->next = head;
    head = tmp;
    printlist(head);
    
    return 0;

【问题讨论】:

1.第 34 行是什么? 2. 把printf's 改成cout's 不代表你改成C++了。 不仅如此,它还有其他小东西。第 34 行是 node_t *result = malloc(sizeof(node_t)); 数数。 Just count ??? - 认真的吗? 我的意思是有人这样做。抱歉,我是新手。 【参考方案1】:

您很可能复制了 List 的 C 示例并尝试将其转换为 C++。

这一行:

node_t *result = malloc(sizeof(node_t));

在 C 中有效,因为在 C 中允许从 void* 到其他类型的指针的隐式转换。注意malloc 返回类型是void*

在 C++ 中,void* 类型被更严格地对待,并且这种隐式转换已被删除。

修复它的一种方法是将malloc 替换为操作员new,正如其他答案所建议的那样(不会复制它)。

其他方法是应用转换node_t *result = (node_t *)malloc(sizeof(node_t));,但这并不好,语言纯粹主义者可能会抱怨 UB。

如果您学习更多现代 C++ 并使用std::unique_ptr,那将是最好的。像这样的:

#include <iostream>
#include <memory>

using namespace std;

struct node 
   int value;
   std::unique_ptr<node> next;
;

void printlist(node *head)

    auto *p = head;
    while(p != NULL)
        cout << p->value << '\n';
        p = p->next.get();
    
    cout << '\n';


std::unique_ptr<node> create_new_node(int value)
    return std::unique_ptr<node>new nodevalue;


void list_insert(std::unique_ptr<node>& head, int value)

    auto tmp = create_new_node(value);
    tmp->next = std::move(head);
    head = std::move(tmp);


int main()

    std::unique_ptr<node> head;

    list_insert(head, 32);
    list_insert(head, 8);
    list_insert(head, 34);

    printlist(head.get());
    
    return 0;

https://godbolt.org/z/bWbva44fa

【讨论】:

考虑使用 std::make_unique (c++14 起) 去掉 create_new_node 函数。 我在想那个,但是聚合初始化不配合它。我将不得不添加显式构造函数。基本上有树方法来解决这个问题:当前方式,make_unique 并添加构造函数,初始化value 或 make_unique 并在单独的行中初始化值(然后返回)。【参考方案2】:

malloc 替换为 new

或许阅读https://www.geeksforgeeks.org/malloc-vs-new/

注意这一行

    node_t *result = new node_t;

在下面的代码中

#include <iostream>
using namespace std;

typedef struct node 
   int value;
   struct node *next;
 node_t;

void printlist(node_t *head)
    node_t *temporary = head;
    while(temporary != NULL)
        cout << temporary -> value << endl;
        temporary = temporary -> next;
    
    cout << endl;

node_t *create_new_node(int value)
    node_t *result = new node_t;
    result->value = value;
    result->next = NULL;
    return result;


int main()

    setlocale(LC_ALL, "portuguese");

    node_t *head;
    node_t *tmp;
    tmp = create_new_node(32);
    head = tmp;
    tmp = create_new_node(8);
    tmp->next = head;
    head = tmp;
    tmp = create_new_node(34);
    tmp->next = head;
    head = tmp;
    printlist(head);
    
    return 0;

godbolt 的运行版本

https://godbolt.org/z/7PvohY4b5

【讨论】:

请注意,我为您提供了一个完全运行的版本,包括您遗漏的 #includeusing 语句。将来在提交 C++ 问题时,如果您确保包含粘贴到 Godbolt 时会证明您的问题的所有内容,您将不太可能被否决。更好地提供一个现有godbolt示例的链接。 感谢它的工作,我一定会从现在开始使用它。 感谢您的反馈,我已经用#include 和 using 语句更新了帖子 我还建议不要到处写using namespace std 而不是std::cout。通常不赞成导入 std 命名空间。它有效,但如果你养成这种习惯,以后可能会遇到问题。如果您发布这样的代码,其他人有时会接您。 内存泄漏:godbolt.org/z/zzd1MMbv4

以上是关于错误:从 'void*' 到 'node_t*' 的无效转换 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

错误:从‘void*’到‘void* (*)(void*)’的无效转换 - pthreads

qsort 给出 [错误]:从 `int (*)(cricketer*, cricketer*)' 到 `int (*)(const void*, const void*)' 的无效转换

使用 C 修改嵌套结构的数据

双环链

不允许使用不完整的类型 c语言

在数组中声明结构类型的元素