For a project I have to use the following definition of Fork: void Fork(VoidFunctionPtr func, int arg);. I need to pass a struct in as the arg so that I can give the forked function more information, but I keep getting errors because a struct is not a int. I am attempting to pass two pointers to buffers into the thread so that the data is shared between the threads. If anyone knows how to trick the function into accepting the struct as an int or another way to accomplish the goal of having shared buffers between threads created by this version of Fork please let me know. P.S. I cannot use the C++ standard version of Fork because the programming I am doing is very low level.
-
If you could provide the code of your attempt it would help. – Dominique McDonnell Oct 01 '15 at 01:49
-
Ok, I'll add it on. I don't think it will be much assistance though. – CSjunkie Oct 01 '15 at 01:50
-
Warning for the future: the fork function doesn't create threads. It creates duplicate processes. – user4581301 Oct 01 '15 at 02:28
-
I know, it creates threads if you then use those duplicate processes to start other functions/programs. Which is how I am using it. – CSjunkie Oct 01 '15 at 02:29
-
Now I'm worried you don't know [the difference between a process and a thread](http://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread). – user4581301 Oct 01 '15 at 02:42
2 Answers
Here are a few ideas of varying quality.
Create a singleton class which contains a vector of your structs. Put a specific instance of the struct into the vector and save the index. Pass that index into
Fork
as the int parameter. YourFork
function can then access the singleton and pull the structure back out.Substantially worse idea. If the size of
int
is the same size as a address on your system you could pass the address to the structure as the int parameter and then cast the hell out of it. Please don't do this.

- 3,721
- 3
- 21
- 32
-
Thanks for the effort but this seems like a very complicated solution. Christian provided an easier solution above. – CSjunkie Oct 01 '15 at 02:47
YOu can use reinterpret_cast< int >(&OYourStruct), then you can pass a pointer to your struct as an int (arg), but is HAS to be a pointer as not the actual struct, as pointers are the same size as ints, and also because it would make very little to pass a struct by value in any case, and in this case, casting a struct to an int would generate everything but the desired result.
when you then need to access your struct from within the function you do the reverse
YourStruct* POYourStruct = reinterpret_cast< YourStruct* >(arg);
YOu can also use the old case cast (int)&OYourStruct and (YourStruct*)arg
But the newer C++ operators are said be more safe.
Actually on most systems (all 32 bit systems) int and void* are both 32 bits, and I am pretty sure that most 64 bit systems either retain that relation or give you a warning at compile time to use a long instead of an int.
But a better solution is actually to exchange your int arg with a void*. Then you can point to any data (also structs) and this is guaranteed to work on all systems. You still have to recast, but this is the way this problem is usually solved when using pure C.
I use a system, where the data pointer is a the type class storage_class*, and that all my storage classes are derived from the this class. And then you cast your base class pointer to the derived pointer your KNOW it to be, and this should be very safe. Just recall what derived class ptr you are pointing to.

- 89
- 7
-
[I recommend reading this](http://stackoverflow.com/questions/3567905/c-is-it-safe-to-cast-pointer-to-int-and-later-back-to-pointer-again) to clear up a few details on the int-pointer relationship. – user4581301 Oct 01 '15 at 02:21
-
That was really helpful but it is tacking gibberish on the end of the buffer. If I load greet with "Hello World" before the fork, within the fork cout << arg->greet outputs "Hello Worl" + gibberish characters. Also I cannot edit the Fork function but I agree, a void pointer would be better – CSjunkie Oct 01 '15 at 02:23
-
user: I just said that on most current 32 bit compilers int and void* are both 32 bits, but in fact the width of int was not defined last time I read the C++ definition, at one point the defintion said something like "int wider than or equal to short, and long wider than or equal to int", Which is why I posted the void* solution, that solution is safe across all platforms, provided you do your casting correctly, wrong casting can result in access violations if you cast to a bigger struct than you passed and otherwise it will give serious bugs in your code, so watch out for the casting. – phazer Oct 01 '15 at 02:29
-
-
@CSjunkie If `SpecialName arg;` is declared inside a function it it likely out of scope and invalid memory by the time the spawned thread gets a chance to look at it. Bits of the memory it did have may have been reassigned and overwritten. – user4581301 Oct 01 '15 at 02:31
-
1Have you reserved room in your string for the '\0' terminating character? That is the most common reason for string gibberish. – phazer Oct 01 '15 at 02:31
-
1You can have a static or global (don't) pointer and then allocate the variable from you function and it will not go out of scope, or if you need a unique one for each struct/object you can just declare a normal memeber varibale (pointer) – phazer Oct 01 '15 at 02:33
-
@ChristianDyrnesli Good call, I left room for it but did not specifically include it in the string. By modifying it to "Hello World\0" it eliminated the gibberish. – CSjunkie Oct 01 '15 at 02:34
-
I never use the int to pointer cast, if I have to I use void*, but many people have used that in the past, the Windows API uses unsafe casts all the time. – phazer Oct 01 '15 at 02:40
-
1CSJunkie: Glad to be of assistance, so my 20 years of solitude behind the keys have not been in vain :) BUT is sounds very much like your are making an array bound overrun, your are most likely writing the '/0' beyond your array, count your string and add 1, that is the length your char arrays should have. – phazer Oct 01 '15 at 02:41
-
CSJunkie: You write that your code is low level, which is fitting because reinterpreting casts really does't do anything other than inform the compiler that you have made this conversion on purpose, so you don't get an "invalid conversion"/"incompatible type" error, the data and the machine code output is not affected. – phazer Oct 01 '15 at 02:48
-
Very nice of you to say so (in the other comment), just remember that a string's length is number of chars + 1 to contain the terminating char. But if you want to avoid all the trouble with zero terminated strings then use the std::string class, it is much more versatile and it is hard to make errors, and when you need the low level string data you just call some_string.c_str() and it return a pointer to a char array with a null-terminated string. Also watch out for those casts, you can generate bugs that take days to find if you EVER find them, I speaking of bitter experience. I – phazer Oct 01 '15 at 03:18