1

If we ignore the aspects:

  1. Bad practice
  2. Unjustified need
  3. and probably others ...

What are the risks (run-time : crash, undefined behavior, segmentation fault. implementation-defined behavior : wrong address generation) of this program as long as the address remains in the interval INT_MIN and INT_MAX:

#include <iostream> using namespace std; #include <sstream> #include <string> #define TAB_SIZE 2 void UseIntAsAdress (unsigned int i) { int *pTab = (int*) i; for (int i=0; i< TAB_SIZE; i++) cout << "tab ["<<i<<"] = "<< pTab[i] <<endl; } int main() { int *pTab = new int [TAB_SIZE]; for ( int i=0; i<TAB_SIZE; i++) pTab [i] = i; std::stringstream streamAdr; streamAdr << pTab; std::string name = streamAdr.str(); unsigned int i = stoi(name.c_str(), 0, 16); UseIntAsAdress (i); delete [] pTab; return 0; } 
15
  • What do you mean by risks? Commented Mar 7, 2020 at 15:44
  • @Cubic in wich case thisi program can Crash or produce a segmentation fault, or undefined behaviour, or out of bound for example. Commented Mar 7, 2020 at 15:45
  • The primary risk here is that address will not remain in interval INT_MIN and INT_MAX... On modern x64 systems it is typically well outside of that range. You should use ::std::uintptr_t if you want to pass some opaque address around as an integer. Commented Mar 7, 2020 at 15:49
  • 2
    "If we ignore [the risks], what are the risks?" I think the most egregious issue is the lack of maintainability. "Why did Parva use an int here instead of a pointer or a std::uintptr_t? What am I missing?" Commented Mar 7, 2020 at 15:56
  • 1
    If you're only interested in potential run-time problems with this code then you need to specify that in the question. Commented Mar 7, 2020 at 16:04

1 Answer 1

3

Your program has implementation-defined behavior. Both the result of streamAdr << pTab; and the result of (int*) i are implementation-defined.

So you need to look at the documentation of your particular compiler to figure out whether this program behaves in the way you expect it to or not.

There is no general guarantee that this will behave correctly.


The cast from pointer to integer can be done much simpler as well:

reinterpret_cast<std::intptr_t>(pTab) 

This is assuming your implementation supports std::intptr_t. Otherwise (in particular pre-C++11) you can try one one of the standard integer types. Compilation should fail if the type used is too small to hold the pointer values and otherwise it will work the same as std::intptr_t.

If then the value resulting from this cast isn't narrowed by conversion to int, the result of casting back to int* will behave as expected (i.e. you get a pointer to the first element of the array back), otherwise it will still have implementation-defined behavior.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks. Unfortunately my implementation does not support std::intptr_t
@Landstalker If you are working with some unusual architecture you might want to add that to the question. Also, you can use one of the standard integer types in place of std::intptr_t. If the type is too small to hold the pointer values, it should give a compilation error, otherwise it should work the same way I described. But as mentioned above it would be weird for it to not define std::intptr_t if such an integer type exists.
i'm talking about C++ version. i have a usual architecture.
@Landstalker ok, then try one of the standard integer types as I mentioned above. Also I suggest you add the corresponding C++ version tag to your question, because it is otherwise generally assumed that you have at least C++11 available. What I wrote in my answer otherwise applies pre-C++11 as well.
I have missed an inlude, i can use std::intptr_t. and im on C++11.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.