7

I want to save int value to a pointer variable. But I get an error:

#include <iostream>
using namespace std;

int main()
{
  int *NumRecPrinted = NULL;
  int no_of_records = 10;
  NumRecPrinted = (int*)no_of_records; // <<< Doesn't give value of NumRecPrinted

  cout << "NumRecPrinted!" << NumRecPrinted;
  return 0;
}

I tried doing this but I get 0 as return:

int main()
{
    int demo(int *NumRecPrinted);
    int num = 2;
    demo(&num);
    cout << "NumRecPrinted=" << num;    <<<< Prints 0
    return 0;
}

int demo (int *NumRecPrinted)

{
    int no_of_records = 11;
    NumRecPrinted = &no_of_records;
}

NumRecPrinted returns as 0

5
  • 1
    You never told us what the error was. Commented Feb 9, 2012 at 14:08
  • Why would you want to do that? There are few good reasons to convert an integer into a pointer, so I am wondering whether what you are trying to do might not be better achieved somehow else. Or do you mean obtain a pointer to an integer? Commented Feb 9, 2012 at 14:21
  • i am doing this inside a function which needs to return the pointer. Commented Feb 9, 2012 at 14:24
  • In your demo function, you modify NumRecPrinted to point to a local variable... It will not be useful outside demo... Commented Feb 9, 2012 at 14:31
  • @AJ. I hope you're not planning a hotel heist. Commented Feb 9, 2012 at 14:36

7 Answers 7

10

It's sometimes useful to "encode" a non-pointer value into a pointer, for instance when you need to pass data into a pthreads thread argument (void*).

In C++ you can do this by hackery; C-style casts are an example of this hackery, and in fact your program works as desired:

#include <iostream>
using namespace std;

int main()
{
  int *NumRecPrinted = NULL;
  int no_of_records = 10;
  NumRecPrinted = (int*)no_of_records;

  cout << "NumRecPrinted!" << NumRecPrinted; // Output: 0xa (same as 10)
  return 0;
}

You just need to realise that 0xa is a hexadecimal representation of the decimal 10.

However, this is a hack; you're not supposed to be able to convert ints to pointers because in general it makes no sense. In fact, even in the pthreads case it's far more logical to pass a pointer to some structure that encapsulates the data you want to pass over.

So, basically... "don't".

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

2 Comments

But if you must ... use intptr_t
... or at least static_assert(sizeof(int) >= sizeof(void*), "the size of int must be greater than or equal to the size of a pointer");, i.e., document your assumptions.
5

You want to be doing this:

NumRecPrinted = &no_of_records;

i.e. you're taking the address of no_of_records and assigning it to NumRecPrinted.

And then to print it:

cout << "NumRecPrinted!" << *NumRecPrinted;

i.e. you're dereferencing NumRecPrinted which will get the int stored at the memory address pointed to by NumRecPrinted.

Comments

3
#include <iostream>
using namespace std;

int main()
{
int *NumRecPrinted = NULL; // assign pointer NumRecPrinted to be valued as NULL
int *NumRecPrinted2 = NULL;
int no_of_records = 10; // initialize the value of the identificator no_of_records 
NumRecPrinted = (int*)no_of_records; // sets a pointer to the address no_of_records
NumRecPrinted2 = &no_of_records; // gives a pointer to the value of no_of_records

cout << "NumRecPrinted!" << NumRecPrinted;  // address of no_of_records 0000000A
cout << "NumRecPrinted!" << *NumRecPrinted2; // value of no_of_records 10
system("pause"); // ninja 
return 0;
}

1 Comment

Why no indentation? And why did you add system("pause")? Doing that makes baby jesus cry.
1

Here is the corrected version:

#include <iostream>
using namespace std;
int main()
{
  int *NumRecPrinted = NULL;
  int no_of_records = 10;
  NumRecPrinted = &no_of_records; // take the address of no_of_records

  cout << "NumRecPrinted!" << *NumRecPrinted; // dereference the pointer
  return 0;
}

Note the added ampersand and the asterisk.

Comments

1

(int *)no_of_records gives you a pointer to the address no_of_records. To get a pointer to the value of no_of_records, you need to write &no_of_records.

Comments

0

It is useful to understand relationship between pointers and integers. They all can be represented as numbers and converted back and forth. Let's look at following example:

int main()
{
    // pointer to int64_t
    int64_t* pointer = new int64_t(5);
    // an integer keeping address of the pointer in decimal format
    int64_t pointerAsNumber = (int64_t) pointer;
    // pointer to int64_t created from  int64_t integer
    int64_t* pointerFromNumber = (int64_t*)pointerAsNumber;

    // both print 5 - number stored in memory cell with address "pointer"
    cout << *pointer << endl;
    cout << *pointerFromNumber << endl;

    // both print same number - the address of memory cell that stores number 5
    // the printed numbers may differ between different program runs
    cout << pointer << endl;
    cout << pointerFromNumber << endl;

    // print address of the memory cell that holds 5 in decimal format
    cout << pointerAsNumber << endl;
    // print address of the memory cell that holds 5 in hexadecimal format
    // note, all 4 printed numbers, pointer, pointerFromNumber, pointerAsNumber and 
    //(hex) << pointerAsNumber are same numbers
    cout << (hex) << pointerAsNumber << endl;

    // now three DIFFERENT numbers will be printed
    // they hold addresses of pointer, pointerFromNumber and pointerAsNumber
    cout << &pointer << endl;
    cout << &pointerFromNumber << endl;
    cout << &pointerAsNumber << endl;

}

I find specially useful possibility to convert user defined data types to and from integers. Here is another example:

struct MyStruct {
    int a;
    int b;
    MyStruct(int a_, int b_) : a(a_), b(b_) {}
};

int main()
{
    MyStruct* ms = new MyStruct(1,2);
    // storing address of ms in msaddr ;
    uint64_t msaddr = (uint64_t)ms;
    // creating another MyStruct from the address
    MyStruct* ms2 = (MyStruct*)(msaddr);
   // the both MyStruct keep same numbers
    cout << ms->a << endl;
    cout << ms->b << endl;
    cout << ms2->a << endl;
    cout << ms2->b << endl;

   // but they are different structs in memory
    cout << &ms << endl;
    cout << &ms2 << endl;
}

Keep in mind, the demonstrated possibilities of converting between integers and pointers are not recommended and should be used with great caution, when at all.

Comments

-1

I really like using union for this sort of stuff:

#include <iostream>
using namespace std;

int main()
{
  static_assert(sizeof(int) == sizeof(int*));

  union { int i; int* p; } u { 10 };

  cout << "NumRecPrinted! " << u.p;
  return 0;
}

1 Comment

That is undefined behavior in C++.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.