void指针转换段错误 [英] void pointer cast segfaults

查看:176
本文介绍了void指针转换段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解void指针的行为。可以有人

向我解释为什么我会为以下程序获得段错误吗?


#include< stdio.h>

void * plusone(void * i){

int * arg =(int *)i;

int result =(* arg + 1);

return(void *)result;

}

int main(){

void * w1 =( void *)10;

void * result = plusone(w1);

printf("%d",*(int *)result);

}


根据gdb,plusone第一行的演员阵容给出了段错误。

为什么?


Markus


PS:我用gcc编译3.2.2

解决方案

Andreas施密特写道:

我试图理解void指针的行为。


你真的想解释为什么访问随机地址

导致你的机器出现段错误。

有人可以解释一下为什么我为
以下程序搞了一个段错误?

#include< stdio.h>

void * plusone(void * i){
int * arg =(int *)i;


(int *)演员表是不必要的。但是如果

结果指针没有适当地对齐int,转换可能会失败。

int result =(* arg + 1);


你试图从你可能不拥有的记忆中获得一个int值。

return(void *)result;


将int转换为void *是实现定义的。

}
int main(){
void * w1 =(void *)10;


再次转换是实现定义的。便携式编程完全没用

,因为你有_no idea_转换为指针时将代表
代表什么。

void * result = plusone(w1);
printf("%d",*(int *)result);


再次尝试从你不拥有的记忆中获取一个int值。


此外,没有尾随\ n,无论如何你都无法保证输出。

}

根据gdb,plusone第一行中的演员给出了段错误。
为什么??




你究竟想做什么?如果它是特定于实现的,那么
然后在实现特定的新闻组中询问。


如果你只是在尝试,那么就会意识到C可能是

_worst_语言通过纯实验学习。


-

彼得


Andreas Schmidt写道:

有人可以向我解释为什么我的
以下程序会出现段错误吗?

根据gdb ,plusone的第一行演员阵容给出了段错误。为什么??
#include< stdio.h>

int main(){
void * w1 =(void *)10;


一般情况下,这是非法的:你不能将int转换成指针。

在你的情况下,你可能会得到一个指向地址的指针
你的电脑上
10号。

void * result = plusone(w1);


现在让我们看看plusone()(我已经重新安排了你的帖子):

void * plusone(void * i){
int * arg =(int *)i;


您正在将地址10转换为指向int的指针。这个

也可能是非法的(例如,在某些系统上,int可以

只驻留在4的倍数地址)。

int result =(* arg + 1);


这绝对是一个问题:你是从

地址10中检索一个int。在像Windows XP或Unix或Linux这样的系统上,

您将收到分段错误,因为您的程序

不允许访问地址10(它只能在其自己的地址空间中访问

地址)。 br />
return(void *)result;


将int转换为指针 - 非法,正如我之前提到的那样。

}


现在我们''回到main():

printf("%d",*(int *)result);


再次,取消引用指向你可能不会拥有的地址的指针,这可能会给你一个分段错误。

}

我试图理解void指针的行为。




你的代码实际上与void指针无关这样,你可以使用int指针或char指针


也遇到了同样的问题。一般来说,你不能用这种方式在

整数和指针之间进行转换。


A" void pointer" (或者更确切地说,指向虚空的指针)是一个指针,你不知道它指向的是什么类型。您可以将其他POINTERS转换为void指针,并将
再次转换回来。你不能将int等转换成

无效指针。


这里有一个你可以做的例子:


void plusone(void * ptr)

{

*(int *)ptr + = 1;

}


int main()

{

int x = 5;

void * ptr = & x;

plusone(ptr);

printf("%d \ n",x);

}


Peter Nilsson写道:

Andreas Schmidt写道:

我试图理解void指针的行为。


将int转换为void *是实现定义的。

}
int main(){
void * w1 =(void *)10;



转换再次是实现定义的。它在便携式编程中完全无用,因为你有_no idea_转换为指针时将代表什么10。




我不喜欢认为这完全没用。以下程序运行正常:


#include< stdio.h>

int main(){

void * i =(void *)10;

printf("%d \ n",(int *)i);

返回0;

}


具体实施是什么意思?你是说我只是很幸运它编译并运行,但这取决于编译器的实现?



I am trying to understand the behavior of void pointers. Can someone
explain to me why I get a segfault for the following program?

#include <stdio.h>

void* plusone(void* i){
int* arg = (int*)i;
int result = (*arg + 1);
return (void*)result;
}
int main(){
void* w1 = (void*)10;
void* result = plusone(w1);
printf("%d", *(int*)result);
}

According to gdb, the cast in the first line of plusone gives the segfault.
Why??

Markus

P.S.: I compiled with gcc 3.2.2

解决方案

Andreas Schmidt wrote:

I am trying to understand the behavior of void pointers.
You''re really trying to explain why accessing random addresses
causes your machine to segfault.
Can someone explain to me why I get a segfault for the
following program?

#include <stdio.h>

void* plusone(void* i){
int* arg = (int*)i;
The (int *) cast is unnecessary. But the conversion may fail if the
resulting pointer is not suitably aligned for an int.
int result = (*arg + 1);
You''re trying to get an int value from memory you probably don''t own.
return (void*)result;
The conversion of an int to a void * is implementation defined.
}
int main(){
void* w1 = (void*)10;
Again the conversion is implementation defined. It is utterly useless
in portable programming because you have _no idea_ what 10 will
represent when converted to a pointer.
void* result = plusone(w1);
printf("%d", *(int*)result);
Again you try and grab an int value from memory you don''t own.

Also, without a trailing \n, you have no guarantee of output anyway.
}

According to gdb, the cast in the first line of plusone gives
the segfault.
Why??



What are you actually trying to do? If it is implementation specific,
then ask in an implementation specific newsgroup.

If you''re just trying things, then realise that C is probably the
_worst_ language to learn through pure experimentation.

--
Peter


Andreas Schmidt wrote:

Can someone explain to me why I get a segfault for the
following program?

According to gdb, the cast in the first line of plusone
gives the segfault. Why?? #include <stdio.h>

int main(){
void* w1 = (void*)10;
In general, this is illegal: you cannot cast an int to a pointer.
In your case, you will probably end up with a pointer to address
number 10 on your PC.
void* result = plusone(w1);
Now let''s look at plusone() (I have rearranged your post a little):
void* plusone(void* i){
int* arg = (int*)i;
You are casting the address 10 to be a pointer to int. This
may also be illegal (for example, on some systems, ints can
only reside at addresses that are a multiple of 4).
int result = (*arg + 1);
This is definitely a problem: you are retrieving an int from
address 10. On a system like Windows XP or Unix or Linux,
you will get a segmentation fault because your program
is not allowed to access address 10 (it can only access
addresses in its own address space).
return (void*)result;
Casting an int to a pointer -- illegal, as I mentioned before.
}
Now we''re back to main():
printf("%d", *(int*)result);
Again, dereferencing a pointer to an address you probably
don''t own, this will probably give you a segmentation fault.
}
I am trying to understand the behavior of void pointers.



Your code really has nothing to do with void pointers as such,
you could have used int pointers or char pointers and
got the same problems. Generally, you cannot convert between
ints and pointers in this way.

A "void pointer" (or more accurately, a pointer-to-void) is
a pointer where you don''t know the type of what it''s pointing
to. You can convert other POINTERS into void pointers, and
convert them back again. You can''t convert ints etc. into
void pointers.

Here''s an example of what you can do:

void plusone(void *ptr)
{
*(int *)ptr += 1;
}

int main()
{
int x = 5;
void *ptr = &x;
plusone(ptr);
printf("%d\n", x);
}


Peter Nilsson wrote:

Andreas Schmidt wrote:

I am trying to understand the behavior of void pointers.

The conversion of an int to a void * is implementation defined.

}
int main(){
void* w1 = (void*)10;



Again the conversion is implementation defined. It is utterly useless
in portable programming because you have _no idea_ what 10 will
represent when converted to a pointer.



I don''t think it''s utterly useless. The following program works fine:

#include <stdio.h>
int main(){
void* i = (void*)10;
printf("%d\n", (int*)i);
return 0;
}

What do you mean by "implementation specific"? Are you saying I''m just
lucky that it compiles and runs, but it depends on the implementation of
the compiler?



这篇关于void指针转换段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆