修改cpp中的void指针

时间:2014-02-15 11:53:49

标签: c++

std :: fread的语法:

size_t fread(void * ptr,size_t size,size_t count,FILE * stream);

我们可以使用字符指针调用std :: fread,并使用相同的字符指针获取读取数据。 例如:

char* data;
fread(data,5,10,file);

我尝试的是创建一个类似的函数,它接受一个字符指针作为void *指针。

#include <iostream>
#include<string.h>

using namespace std;

void modify(void* ptr)
{
    char* temp = new char[50];
    strcpy(temp,"testing");
    __ptr=(void*)temp;
    std::cout<<"__ptr="<<(char*)__ptr<<endl;
}

int main()
{
    char* str;
    modify(str);
    cout<<"str="<<str;
    return 0;
}

我用http://www.compileonline.com/compile_cpp11_online.php尝试了上面的代码,输出为

__ PTR =测试

STR =

(a)为什么 str不打印字符串&#34;测试&#34;?

我将动态分配的变量的地址分配给ptr。 所以价值&#34;测试&#34;即使控件从方法返回,也必须在堆中可用。

(b)如何修改功能以便我将输出作为

__ PTR =测试

STR =测试

但是函数原型无法修改。

请帮忙。

希望问题很明确。

2 个答案:

答案 0 :(得分:4)

问题是函数modify()会引用void*,但实际上是在传递char*。这不是有效的C ++,不应该编译。

那就是说,有一些旧的C ++编译器(Visual C ++ 6?)有一种扩展,允许你这样做。这是在您调用modify(str)时,编译器正在创建类型为void*的临时值并将其初始化为值str。然后临时传递给函数并获取分配的内存的地址。但是,显然,str原始值永远不会被修改,因此它仍未被初始化。

这就是原始C ++规则禁止这种情况的主要原因:保护您免受此类错误。

您有两种解决方案:

  • 使用正确的指针类型声明函数:void modify(char*& ptr)
  • 更改编译器!
  • 如果你真的想要这个功能你可以用modify(reinterpret_cast<void*&>(str))来称呼它,但我推荐它!

顺便说一下,永远不要用两个下划线(__ptr)来命名你的标识符,这些名称只保留给编译器编写者。

啊!我现在理解OP问题:他的想法是写一个包装器给fread,它分配内存,从文件中读取并返回指针。如果你以通常的方式返回指针会更容易。使用您的modify()简化示例:

void* modify()
{
    char* temp = new char[50];
    strcpy(temp,"testing");
    return temp;    
}

然后,称之为:

char *ptr = static_cast<char*>(modify());

答案 1 :(得分:1)

从@rodrigo的宝贵答案和评论中,我能够解决我的问题。 我修改了这个功能。

void modify(void* ptr)
{
    char* temp;
    temp = (char *)ptr;
    strcpy(temp,"testing");
}

这解决了所有问题!