473,398 Members | 2,088 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

void pointer cast segfaults

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
Nov 14 '05 #1
12 6314
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

Nov 14 '05 #2
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);
}

Nov 14 '05 #3
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?


Nov 14 '05 #4
Andreas Schmidt wrote:
The following program works fine:

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


OK, now I understand I am really just printing the pointer address here...

A.
Nov 14 '05 #5
Andreas Schmidt <sc**********@gmx.de> writes:
Andreas Schmidt wrote:
The following program works fine:

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


OK, now I understand I am really just printing the pointer address here...


You *might* be printing the address. By using an int* argument with a
"%d" format, you're invoking undefind behavior. (In particular, it's
not uncommon for int and int* to have different sizes.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #6
Andreas Schmidt wrote on 05/05/05 :
#include <stdio.h>

void *plusone (void *i)
{
/* -ed- the value of i is unspecified */

int *arg = (int *) i;
/* -ed- the value of arg is unspecified */

int result = (*arg + 1);
/* -ed- the value of *arg is undefined */

return (void *) result;
/* -ed-
* I'm lost.
* Why in the world are you frankensteining your code like that ?
* Cast is evil, didn't your mom told you that before ?
*/
}

int main (void)
{
/* -ed-
* the result of the conversion of an integer to a pointer constant
* is implementation defined. On my platform, the result is
unspecified.
*
* Using the value of w1 invokes an undefined behaviour.
*/
void *w1 = (void *) 10;

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

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair

Nov 14 '05 #7

"Andreas Schmidt" <sc**********@gmx.de> wrote in message
news:3d***********@individual.net...
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; change this to: return (void*)&result;
return the address of result (cast to a void *) [or a pointer to result]
}
int main(){
void* w1 = (void*)10; change this to: void* w1 = (void*)&10;

w1 is assigned the address of 10 (cast to a void *) [or a pointer to
address] void* result = plusone(w1);
printf("%d", *(int*)result);
}

Cian
Nov 14 '05 #8
On Thu, 05 May 2005 09:47:49 +0100, Cian wrote:

"Andreas Schmidt" <sc**********@gmx.de> wrote in message
news:3d***********@individual.net...
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; change this to: return (void*)&result;
return the address of result (cast to a void *) [or a pointer to result]
}
int main(){
void* w1 = (void*)10;

change this to: void* w1 = (void*)&10;


10 isn't an lvalue, it is not a valid operand for &. You could change it
to

int value = 10;
void *w1 = &value;
w1 is assigned the address of 10 (cast to a void *) [or a pointer to
address]


Since 10 is not an object or function it has no address.

Lawrence
Nov 14 '05 #9
"Cian" <ci******@REMOVEfastmailTHIS.fm> writes:
void* plusone(void* i){
int* arg = (int*)i;
int result = (*arg + 1);
return (void*)result;

change this to: return (void*)&result;
return the address of result (cast to a void *) [or a pointer to result]


Not a good idea to return a pointer to a local variable.

Jim

--
I was born not knowing and have had only a little time to change
that here and there. -- Richard Feynman
Nov 14 '05 #10
"Old Wolf" <ol*****@inspire.net.nz> writes:
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.


Not quite. C99 6.3.2.3p5 says:

An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined, might
not be correctly aligned, might not point to an entity of the
referenced type, and might be a trap representation.

(The "previously specified" refers to null pointer constants.)
In your case, you will probably end up with a pointer to address
number 10 on your PC.


Probably. A footnote says:

The mapping functions for converting a pointer to an integer or an
integer to a pointer are intended to be consistent with the
addressing structure of the execution environment.

Of course, the result is vanishingly unlikely to be useful.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #11
On Thu, 05 May 2005 06:25:39 GMT, Keith Thompson <ks***@mib.org>
wrote:
Andreas Schmidt <sc**********@gmx.de> writes:
Andreas Schmidt wrote:
The following program works fine:

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


OK, now I understand I am really just printing the pointer address here...


You *might* be printing the address. By using an int* argument with a
"%d" format, you're invoking undefind behavior. (In particular, it's
not uncommon for int and int* to have different sizes.)


It also invokes undefined behavior in those cases where the value 10
does not represent the suitably aligned value for the address of an
int.
<<Remove the del for email>>
Nov 14 '05 #12
In article <3d***********@individual.net>,
Andreas Schmidt <sc**********@gmx.de> wrote:
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?


No, you are extremely unlucky.

Luck is when a crappy program crashes on you, giving you the chance the
fix it and may be to learn something.
Nov 14 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

52
by: Vladimir Grul | last post by:
Hello, I have a class member function declared as class some_class { .... virtual int call(void); }; Can I use this-> inside the function body?
16
by: He Shiming | last post by:
Hi, I'm having a little bit of trouble regarding pointer casting in my program. I don't understand why the following two cases produce different results. Case 1: IInterface *pInterface = new...
15
by: Stig Brautaset | last post by:
Hi group, I'm playing with a little generic linked list/stack library, and have a little problem with the interface of the pop() function. If I used a struct like this it would be simple: ...
188
by: infobahn | last post by:
printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
5
by: Stijn van Dongen | last post by:
A question about void*. I have a hash library where the hash create function accepts functions unsigned (*hash)(const void *a) int (*cmp) (const void *a, const void *b) The insert function...
27
by: Erik de Castro Lopo | last post by:
Hi all, The GNU C compiler allows a void pointer to be incremented and the behaviour is equivalent to incrementing a char pointer. Is this legal C99 or is this a GNU C extention? Thanks in...
49
by: elmar | last post by:
Hi Clers, If I look at my ~200000 lines of C code programmed over the past 15 years, there is one annoying thing in this smart language, which somehow reduces the 'beauty' of the source code...
6
by: jacek.dziedzic | last post by:
Hello! I have some legacy C code which expects a pointer to a function to be evaluated at one point. Because of the pointer-to-function vs. pointer-to-member incompatibility, this needs to be a...
10
by: kkirtac | last post by:
Hi, i have a void pointer and i cast it to an appropriate known type before using. The types which i cast this void* to are, from the Intel's open source computer vision library. Here is my piece...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.