函数参数中的void指针

时间:2015-06-20 14:27:11

标签: c++ pointers parameter-passing void-pointers

考虑以下计划:

Intent intent = new Intent(youractivity.this, Youractivity.class);
 finish(); 
startActivity(intent);

如果我更改函数调用语句,如下所示:

#include <iostream> void f(void* a) { std::cout<<"(void*)fun is called\n"; std::cout<<*(int*)a<<'\n'; } int main() { int a=9; void* b=(int*)&a; f(b); return 0; }

它仍然编译精细&amp;在运行时崩溃。为什么?是什么原因?我不应该得到编译时错误吗?因为调用函数的正确方法是f(b)。对?另外,为什么允许将NULL传递给参数类型为(void *)的函数?

请纠正我如果我遗漏了某些东西或理解错误的东西。

7 个答案:

答案 0 :(得分:6)

  

它仍然编译精细&amp;在运行时崩溃。为什么?是什么原因?

因为void*是一种删除所有类型安全和类型检查的技术。

  

我是否应该收到编译时错误?

通过使用void*而不是正确的指针类型int*,您明确告诉编译器不要告诉您如果您使用的类型不正确或未定义方式。

  

因为调用函数的正确方法是f(b)。正确?

您的功能声明内容不同意。

    std::cout<<"(void*)fun is called\n";
    std::cout<<*(int*)a<<'\n';

上面的内容暗示应该传递指向int的指针:

void f(void* a)

声明暗示应传递某些指针,并且不会产生任何其他限制。

答案 1 :(得分:2)

void*可以捕获任何类型的指针,void**没有例外

答案 2 :(得分:1)

<强>第一

您可以function updateData(){ ... yScale2 = d3.scale.linear() .domain([0, d3.max(dataset, function(d) { return d3.max(d, function(d) { return d.y0 + d.y; }); }) ]) .range([h - 10, 0]); // set scale yAxis.scale(yScale2); // redraw it d3.select('.yaxis').call(yAxis); } 指向void*。您的代码是显示危险void**指针有多危险的众多示例之一。

<强>第二

您应该使用类型转换:

void*

而不是您正在使用的c样式转换:

void* b = static_cast<int*>(&a);

答案 3 :(得分:1)

确定。

按要求。

不要使用void指针,除非你想不到任何其他方法。

然后再去睡觉再思考。

Void指针使程序员忘记了类型。这意味着编译可以放弃简单的检查。这在我看来也意味着程序员已经失去了情节。

如果你愿意的话,请打听我。

使用类型具有编译器可以为您检查的奢侈品。例如。事情是如何相关的。如何对待那个对象。

但是使用无效指针你很自己。祝你好运

答案 4 :(得分:1)

您不会收到编译时错误,因为f(&b)会调用f并将b的地址作为参数传递,然后将其转换为void* 。你得到一个运行时错误,因为那样,你试图将一个整数的指针强制转换为整数。 但是,正如其他人所说,这样做非常糟糕。

答案 5 :(得分:1)

  

如果我改变函数调用语句,如下所示:   F(和b);   它仍然编译精细和在运行时崩溃。为什么呢?

您的函数f(void*)将接受指向任何类型的指针,无需投诉。任何指针都会静静地转换为void指针。指向指针的指针仍然是指针。所以你的第二个案例确实编译得很好。然后它崩溃了。也许

在第一种情况下,您从指向int的指针转换为指向void的指针返回指向int的指针。通过void*(以及char*)进行的往返转换必须有效。在第二种情况下,您从void**转换为void*int*。现在,您正在调用未定义的行为。什么都可以。在我的计算机上,我的编译器,你的代码运行得很好。它打印垃圾。我很确定你的代码不会擦除我的硬盘,但它可以。任何事情都与未定义的行为有关。不要调用未定义的行为。

支持void*的原因具有历史意义。有很多旧的C和C ++代码使用void指针。编写使用void指针的新C ++代码的唯一原因是,如果您需要与使用void指针的旧函数之一进行交互。

答案 6 :(得分:0)

我发现自己在这里因为我正在完成一项要求相同功能的家庭作业。在结合每个评论之后,这就是我提出的。

// A function that accepts a void pointer
void f(void* a)
{
    std::cout<<"(void*)fun is called\n";
    std::cout<< "value for a: " << *(int*)a << '\n';
}


int main() {
    int a = 9;
    void* c = static_cast<int*>(&a);

    int b = 3;
    f(&b);
    f(c);
}