[英]Acessing memory referenced by void pointer
I am getting my head around void pointers in C++ and as an exercise have written the following code:我对 C++ 中的 void 指针有所了解,并作为练习编写了以下代码:
void* routine(void* number){
int n = (int)number;
int* np = (int*)number;
cout<<"void pointer: "<<number<<endl;
cout<<"casted int pointer: "<<np<<endl;
cout<<"int pointer content: "<<*np<<endl;
return (void*)NULL;
}
int main(){
int num = 1;
routine((void*)num);
}
This breaks in runtime as the pointer np
, casted from void*
to int*
is dereferenced.这会在运行时中断,因为从
void*
转换为int*
的指针np
被取消引用。
I attempt to pass the argument number
as a void pointer and dereference its value inside the function.我尝试将参数
number
作为 void 指针传递,并在 function 中取消引用它的值。 Arithmetic on void pointers are illegal, therefore what I try to do is cast the pointer to an int*
and attempt to dereference this casted copy. void 指针的算术是非法的,因此我尝试将指针转换为
int*
并尝试取消引用这个转换后的副本。
I somewhat expect this not to work, but if that were the case I would also expect some sort of compiler error as is the case when this attempt is made without the int*
cast.我有点期望这不起作用,但如果是这种情况,我也会期望某种编译器错误,就像在没有
int*
强制转换的情况下进行此尝试一样。 The reason I sort of expect it to work is that the casted pointer retains the original void pointer address, meaning that after the cast it appears to be just a regular memory address, which I see no reason to be inaccessible by regular dereference.我有点期望它起作用的原因是强制转换的指针保留了原始的 void 指针地址,这意味着在强制转换之后它似乎只是一个常规的 memory 地址,我认为没有理由通过常规取消引用无法访问该地址。 The
n
variable is a copy of the referenced value, but is just that - I cannot change the actual value in the memory address. n
变量是引用值的副本,但仅此而已 - 我无法更改 memory 地址中的实际值。
Is this possible with a void pointer?这可以使用 void 指针吗? What am I missing?
我错过了什么?
The usual &num
will do.通常的
&num
就可以了。
routine(&num);
Any object pointer implicitly converts to void*
.任何 object 指针都会隐式转换为
void*
。 On the callback function you'll have to convert it back to the correct pointer type (use static_cast
not C-style cast, that will prevent you from accidentally mixing up pointers containing addresses with integer values that are not memory addresses).在回调 function 上,您必须将其转换回正确的指针类型(使用
static_cast
而不是 C 风格的强制转换,这将防止您意外地将包含地址的指针与 integer 值而不是 ZCD69B4957F06BDE81917 地址混淆)
void* routine( void* user_ptr )
{
int* np = static_cast<int*>(user_ptr);
Other pointers which aren't object pointers won't implicitly convert to void*
, including function pointers and pointer-to-members.其他不是 object 指针的指针不会隐式转换为
void*
,包括 function 指针和指向成员的指针。 Adding a cast will force the compiler to do the wrong thing and be quiet about it, but (apart from the return value of dlsym()
or its Windows equivalent GetProcAddress()
) it isn't safe to mix void*
with these other pointer varieties anyway.添加强制转换将迫使编译器做错事并对此保持沉默,但是(除了
dlsym()
或其 Windows 等效的GetProcAddress()
的返回值之外)将void*
与这些其他指针混合是不安全的反正品种。
void* routine(void* number){
int n = (int)number;
int* np = (int*)number;
cout<<"void pointer: "<<number<<endl;
cout<<"casted int pointer: "<<np<<endl;
cout<<"int pointer content: "<<*np<<endl;
return (void*)NULL;
}
int main(){
int num = 1;
int* num_p = #
routine((void*)num_p);
}
Pointing to num
s address before passing does the trick.在传递之前指向
num
的地址就可以了。 The casting of an integer to a void pointer makes no sense.将 integer 转换为 void 指针是没有意义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.