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

AJ.
  • 2,561
  • 9
  • 46
  • 81

7 Answers7

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".

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 1
    But if you must ... use [intptr_t](http://stackoverflow.com/questions/6326338/why-when-to-use-intptr-t-for-type-casting-in-c) – Useless Feb 09 '12 at 14:24
  • 1
    ... 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. – R. Martinho Fernandes Feb 09 '12 at 14:34
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.

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
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;
}
Dzek Trek
  • 338
  • 3
  • 14
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.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
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.

Abrixas2
  • 3,207
  • 1
  • 20
  • 22
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.

Andrushenko Alexander
  • 1,839
  • 19
  • 14
0

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;
}
Gigi
  • 4,953
  • 24
  • 25