【问题标题】:Error invalid conversion from ‘void*’ to ‘char*’从“void*”到“char*”的错误无效转换
【发布时间】:2019-02-05 04:31:54
【问题描述】:

尝试查看过去处理此问题的问题,但所有这些问题似乎都与 C++ 而不是 C 相关。而且我必须用 C 编写程序。所以我有这部分代码应该执行以下操作:修改strp 指向的现有 kstring 至少为 nbytes 字节长......等等。但是我有该函数的代码,但我不断收到错误消息:从“void*”到“char*”的无效转换。

typedef struct
    {
        char *data;
        size_t length;
    } kstring; 

功能:

void kstrextend(kstring *strp, size_t nbytes)
{
    char *nwData;
    int lnth=strp->length;
    if(lnth < nbytes)
    {
        // new array allocate with large size and copy data to new array
        nwData = realloc(strp->data, nbytes);
        // call abort in case of error
        if(nwData == NULL)
        {
            abort();
        }
        //Making strp->data point to the new array
        strp->data = nwData;
        //Setting strp->length to the new size.
        strp->length = nbytes;
        // filled with '\0' in remaining space of new array
        for (int lp = lnth; lp < nbytes; lp++)
        {
            strp->data[lp] = '\0';
        }
    }
}

调用函数的主要部分:

name.data = (char*)calloc(sizeof("Hello"), 1);
strcpy(input, "Hello");
name.length=5;
kstrextend(&name,40);
printf("%s %d",name.data,name.length);

【问题讨论】:

  • length 和实际分配的字节数似乎有些不一致。例如,sizeof("Hello") 是 6,因为它包含尾随空字节,但您使用 5 表示 length,并且代码似乎将 length 视为分配的字节数,而不是少一个。跨度>
  • 你确定编译成C吗?
  • 错误呈现在哪一行?我假设它是 realloc 行?
  • @TomNorth:您必须将其编译为 C++,而不是 C。C 允许在 void * 和其他指针类型之间直接赋值,而 C++ 不允许。你不应该从 C 编译器中得到这个错误。你是如何编译这段代码的?请显示您正在使用的确切命令。
  • @TomNorth FYI Putty 只是一个 ssh 终端客户端 - 它与您使用的编译没有任何关系。正如 John Bode 所提到的,将来您应该包含用于编译您遇到问题的命令。此外,如果文件是 C 文件,它应该具有 .c 扩展名而不是 .cc,正如我在答案中提到的,您应该使用 gcc 而不是 g++。

标签: c


【解决方案1】:

问题是你在哪里调用 realloc:

// new array allocate with large size and copy data to new array
nwData = realloc(strp->data, nbytes);

nwData 是一个char * 类型,但realloc 返回一个void *。请参阅https://en.cppreference.com/w/c/memory/realloc 了解更多信息。您应该像设置name.data 时那样转换为char *

nwData = (char *)realloc(strp-&gt;data, nbytes);

我假设您正在使用 g++ 进行编译?如果您正在编写 C 程序,则应使用 gcc 进行编译,它将根据 C 语言语义而不是 C++ 进行编译。

附带说明,我看到您在循环中手动将数组的其余部分设置为 \0

// filled with '\0' in remaining space of new array
for (int lp = lnth; lp < nbytes; lp++)
{
    strp->data[lp] = '\0';
}

使用内置的memcpy 函数通常比使用循环更快(和更好的代码风格):

memset(strp->data + lnth, nbytes - lnth, '\0');

【讨论】:

  • 能否对这个答案投反对票,请解释原因?
  • 我没有投反对票。但是我可以理解为什么有人会这样做,尤其是因为您还强调了 C 和 C++ 语义之间的区别。阅读stackoverflow.com/questions/605845/…
  • 我不确定您要表达什么观点。 C 和 C++ 是具有不同语义的不同语言。这与将 malloc 的 void* 结果转换为另一种指针类型是否合理是一个单独的论点。他的问题是为什么他的程序无法编译,那是因为他编译的是 C++ 而不是 C。
  • 来自问题:“而且我必须用 C 语言编写程序” - 你建议实际使用 C 编译器是好的。添加演员表的建议是 C++ 编译器的安抚,单调且完全无关紧要。 IE。不好。
  • 哦,你似乎把 memcpymemset 混淆了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 2011-06-29
  • 1970-01-01
相关资源
最近更新 更多