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

int main() {
    void *malloc(size_t size);
    char *ptr, *retval;
    ptr = (char *)calloc(10, sizeof(char));

    if (ptr == NULL)
        printf("calloc failed\n");
    else
        printf("calloc successful\n");

    retval = realloc(ptr, 5);

    if (retval == NULL)
        printf("realloc failed\n");
    else
        printf("realloc successful\n");

    free(ptr);
    free(retval);
}

这是我的代码,错误出现在第 14 行,它说

从“void*”到“char*”的无效转换

4

4 回答 4

10

您可以像使用 malloc 一样将 realloc 的结果转换为 (char*)。

retval = (char*)realloc(ptr, 5);

具有讽刺意味的是,尽管您编写的是完全合法的“C”代码......只是不是您需要强制转换的 C++。因此,您也可以尝试将编译器设置为将代码编译为“C”,因为您没有执行任何 C++,这同样可以解决问题。也就是说,上面的修改也是完全合法的 C ......所以可以在 C++ 和 C 下编译。

编辑:正如softy正确指出你重新分配ptr并将指针位置存储到retval中,这意味着ptr可能指向无效内存,你不应该释放它。最好的情况是两次释放相同的内存,最坏的情况是在已经释放的内存上调用 free(通过 realloc)。无论哪种方式都不好(tm)。实际上,您正在调用一些严重的“未定义行为”。

于 2012-05-21T18:12:23.340 回答
1

其他人注意到您的 C 代码正在编译为 C++ 代码。强制转换在 C 中是不必要的,但在 C++ 中是必需的。在 C++ 中,您应该使用向量(或字符串)。

以下是对您的代码的一些观察:

  1. 不要重新声明 malloc。包括 stdlib.h 将为您做到这一点。幸好你已经成功地复制了它的声明,所以它只是多余的(并且让其他阅读代码的人感到困惑)。如果你的声明错误,你有未定义的行为。

  2. 如果 realloc 成功,不要释放 'ptr'。

  3. 有些人可能会指出,在某些深奥的系统中,calloc 可能无法达到您的预期(特别是对于指针和浮点类型)。考虑到无论如何您都希望用合适的值初始化动态分配的空间,调用 calloc 比调用 malloc 是多余的。

于 2012-05-21T18:41:12.593 回答
1

您不能两次释放指针。这里 retval 和 ptr 都指向同一个位置,添加此代码并在免费调用之前检查:

printf("%p \n ",ptr);
printf("%p \n",retval);

realloc 缩小了大小,但指针位置保持不变。你也可以试试这个:

if(ptr == retval)

/* delete either ptr or retval - just for sake of this programm , Idealy you shouldnt free the the pointer like this as Rightly Suggested by **Goz** in C++/c*/

只是为了让它工作。否则它可以通过 gcc 很好地编译,但是如果你运行它会给出一个脏堆栈跟踪,因为你试图释放相同的指针两次。内存分配函数的底层中断调用可能会也可能不会分配相同的指向它的指针。如果您将尺寸扩大到 30 或 50,它可能会给您不同的指针。

rgds,软软的

于 2012-05-21T18:22:37.077 回答
0

如果要编译,请使用 C 编译。看起来好像您正在使用 C++ 编译。它是有效的 C 但不是有效的 C++。在大多数使用小写 .c 扩展名的编译器中,编译器会自动使用 C 编译。.cpp 将导致 C++ 编译,.C(大写)也可能导致 C++ 编译(例如在 gcc 中)。

于 2012-05-21T18:31:06.917 回答