【问题标题】:Modifying void pointer in cpp修改cpp中的void指针
【发布时间】:2014-03-14 20:45:54
【问题描述】:

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=testing

str=

(a)为什么 str 没有打印字符串“testing”?

我将动态分配变量的地址分配给 ptr。 因此,即使控件从方法返回后,堆中的值“testing”也必须可用。

(b)我怎样才能修改函数,这样我就可以得到输出

__ptr=测试

str=测试

但是函数原型不能修改。

请帮忙。

希望问题很清楚。

【问题讨论】:

  • 标题与正文不匹配,随机指针滥用会产生随机结果。不是一个有用的问题。
  • 此代码在没有警告/错误的情况下无法编译 (ideone.com/yrOcHS)。请先解决这个问题,然后我们可以重新访问。
  • 这基本上是C,如果你想以C++的方式做事,你应该使用迭代器和流。
  • @MSalters..实际上我正在为 fread 函数编写一个包装函数。我只是在一个简单的例子的帮助下缩短了这个问题。 “随机指针虐待”你能帮我解释一下你为什么这样说吗?如果您是对的,那么我认为您的回答可能会帮助我解决问题。 :)
  • 这甚至不会编译。没有引用要调用的char* 的函数。如果这适合您,请告诉我们您的工具链是什么(如果是 TurboC++,我不会对它接受的废话感到惊讶)。

标签: c++


【解决方案1】:

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

也就是说,有一些旧的 C++ 编译器(Visual C++ 6?)有一种扩展,可以让你这样做。也就是说,当您调用modify(str) 时,编译器正在创建一个void* 类型的临时值并将其初始化为str 的值。然后将临时值传递给函数并获取分配内存的地址。但是,很明显,str 原始值从未被修改过,因此它保持未初始化状态。

这就是最初的 C++ 规则禁止这样做的主要原因:保护您免受此类错误的侵害。

您有两种解决方案:

  • 使用正确的指针类型声明函数:void modify(char*&amp; ptr)
  • 更改编译器!
  • 如果您真的想要该函数,您可以使用 modify(reinterpret_cast&lt;void*&amp;&gt;(str)) 调用它,但我建议这样做!

顺便说一句,切勿使用两个下划线 (__ptr) 命名您的标识符,这些名称仅供编译器编写者使用·

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

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

然后,调用它:

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

【讨论】:

  • 所以你认为编译器正在创建一个临时作为非常量引用传递?埃加兹。
  • @WhozCraig:是的,我认为 VC++6(可能还有以后的版本,我没怎么用过)曾经允许这种代码。
  • 我知道 VC++ 至少从 2008 年开始支持对 return values 的非 const 引用,但是这(你所描述的)是丑陋的大写 U。跨度>
  • @WhozCraig:看看list of VC++ extensions。其他扩展或多或少是明智的,但那是疯狂的!
  • @NidhinJoseph: fread() 不会修改指针,它会修改指针指向的内存。这是两个完全不同的东西。想想ptr = X*ptr = X
【解决方案2】:

从@rodrigo 的宝贵答案和 cmets 中,我能够解决我的问题。 我修改了函数。

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

这解决了所有问题!

【讨论】:

  • 如果应用于当前存在问题的代码,这将写入一个野指针,因为 str 从未初始化为指向任何地方。
猜你喜欢
  • 2012-01-28
  • 2011-06-23
  • 2014-05-30
  • 2012-11-23
  • 1970-01-01
  • 2013-12-18
  • 2022-01-04
  • 2011-04-01
相关资源
最近更新 更多