2

Seeing this thread I wrote the following: How do I convert from void * back to int

#include <iostream>
#include <stdlib.h>
using namespace std;

int main (int argc, char *argv[])
{
    void* port = (void*) atoi (argv[1]);

    cout << "\nvalue: \n" << atoi (argv[1]) << "\n";

    int h = *((int *)port);
    cout << h;
}

output:

anisha@linux-dopx:~/> ./a.out 323

value: 
323
Segmentation fault
anisha@linux-dopx:~/>

GCC

What's the point that I am missing?

Community
  • 1
  • 1
Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411
  • I don't think casting from int to void* is intentional at all. That alone causes the seg fault when you try to dereference void* due to unallocated memeory at location 323. – ksming Jan 11 '12 at 08:18
  • @ksming which line to change? – Aquarius_Girl Jan 11 '12 at 08:42
  • The difference with the question that you link to is that there a cast from int* is done to void*, so there you should cast back to int*. You do a cast from int to void* so in this case you should cast back to int. However, try avoid this casting. – stefaanv Jan 11 '12 at 09:06
  • See my comment on Luchian's answer to avoid the casting altogether if you need this for creating threads. – stefaanv Jan 11 '12 at 09:19

7 Answers7

5

Okay, please ignore my previous answer. Instead of (char*)port - (char*)0, please do the following:

int h = *(int *)(&port);

You're getting the address of port:

&port

Casting the address to an int *:

(int *)(&port)

Then dereferencing the address to get back the integer value you put into port:

*(int *)(&port)
Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
3

Ignoring potential issues with the intermediate conversions, you start with an int and end up treating it as if it were int*. In other words, you treat the result of atoi() as an address, and try to read the memory at that address.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

I made the following adjustment, based on this SO answer:

#include <iostream>
#include <stdlib.h>
using namespace std;

int main (int argc, char *argv[])
{
    void *port = (void *) atoi(argv[1]);

    cout << "\nvalue: \n" << atoi (argv[1]) << "\n";

    int h = (char*)port - (char*)0;    
    cout << h;
}

Result:

$ g++ -Wall test.cpp
$ ./a.out 323

value: 
323
323
Community
  • 1
  • 1
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • yes, it worked, thanks. could you explain it? `(char*)port - (char*)0;` – Aquarius_Girl Jan 11 '12 at 08:51
  • This seems like undefined behavior to me: arithmetic with a pointer that points nowhere and a null-pointer that doesn't necessary points to address 0x00000000... I can see how it should work with most common compilers. – stefaanv Jan 11 '12 at 09:11
  • My thoughts on this may be wrong, but I'll throw this out there for others to comment on. The subtraction operator can take two pointers of the same type. Subtracting the address of '0' from the address of a `char *` of `port` (here, really an `int`) returns the number of 1-byte `char` elements between them, the number being implicitly cast back to an `int`. (Try replacing `char *` with `int *` and your answer `h` should be divided by `sizeof(int)`, often four bytes.) – Alex Reynolds Jan 11 '12 at 09:20
  • Please ignore this answer and see my other one. I think my newer answer makes more sense and is more readable. – Alex Reynolds Jan 11 '12 at 09:30
0

use this

int h = ((int )port);

Because you converted int to void*

Now convert back void* to int by ((int )port)

So use int h = ((int )port);

shrotriya
  • 26
  • 4
0

You try to typecast port to an int pointer, but it is not a pointer. It is a value. You are using 323 as a pointer. If you want to get an int * then either typecast argv[1] or a pointer to port. Port should also probably not be declared as a void * as it is processed to an int in atoi(), it should probably be simply an int.

Dan
  • 10,531
  • 2
  • 36
  • 55
0

You're dereferencing a pointer which points to memory you don't own, which is undefined behavior.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • @AnishaKaul it's not a specific line, it's the logic that's faulty. `void* port = (void*) atoi (argv[1]);` this gives you a pointer to memory you don't own, which you're trying to de-reference. – Luchian Grigore Jan 11 '12 at 08:42
  • actually, the port needs to be passed as a void pointer to a function "pthread_create". That's why I typecasted it. – Aquarius_Girl Jan 11 '12 at 08:45
  • 1
    @anisha: there are discussions about this, but I think passing to pthread_create should be done by dynamic memory: int\* pArg = new int; \*pArg = atoi(...); pthread_create(...pArg...); and delete the argument inside the new thread. It is not the most C++-like, but it respects the void* parameter. – stefaanv Jan 11 '12 at 09:17
0

Change below line

void* port = (void*) atoi (argv[1]); 

to

int port = atoi (argv[1]); 
harishr
  • 17,807
  • 9
  • 78
  • 125