You are here:

C++/Pointers in C++



struct test{int a;

char *buff;

void main()
  char *nav;




  ptr1=new test;



  ptr1=(struct test*)nav;




i want ptr1->a should be giving 5 but it doen't give, what to do
It gives me some garbage value,
Am i doing the right thing

Sorry but no you are not doing the correct thing.

1/  Header files:
#include<iostream.h>  // old C++ header - Standard name is <iostream>

#include<conio.h>     // not C or C++ header, not required

#include<string>      // C++ standard string header, not required

#include<stdlib.h>    // C header - standard C++ header is <cstdlib>

#include<malloc.h>    // C header only, not required (probably!)

2/ Use of global objects very questionable:
struct test{ int a; } ptr,*ptr1,*ptr2;

char *buff;

Global data should be reduced in any program as much as possible. There is absolutely no need for it in this example that I can see. Ok the example is small so it probably does not matter but why get into bad habits?

Oh, and the object ptr is not, as its name suggests, a pointer. Names of type, objects etc. should be chosen to be meaningful. In this case the name ptr is misleading.

What are buff and ptr2 for? They seem not to be used at all.

3/ Use of non-standard signature for main:
void main()

The above form of main is a Microsoft specific perversion. The _only_ standard forms of main are:

   int main() { /* ... */ }


   int main( int argc, char * argv[] ) { /* ... */ }

Oh, and for main and main only, although an int return type is specified an actual return statement can be left out and return 0 is assumed. Note that older Microsoft compilers do not accept this usage (hence their support for the void main() form maybe) and return 0 will need to be used explicitly.

4/ Use of malloc in C++ is very, very questionable:

The function malloc is part of the old C dynamic allocation support. In C++ we use new and delete (as you do elsewhere). This is probably not too important here but is when the objects allocated are user defined class types that have non-trivial constructors and/or destructors.

Also you are using a C-style sledgehammer cast. In C++ one of the new specific cast operation cast operators should be used: static_cast, const_cast, dynamic_cast or reinterpret_cast. The latter is the most dangerous of the new casts as it generally just reinterprets the bits as the requested type with no modification. It is also the one to use here.

Note that you can do away with all that nastiness as you can use new [] to create arrays of objects (with delete [] to destroy an array):

   char * nav = new char[1000];

And of course 1000 is a magic number. It is meaningless. Give such values names by using a constant:

   size_t const NavSize = 1000;
   size_t const NavSize( 1000 );

   char * nav = new char[NavSize];

Ok so NavSize is probably not the most meaningful name in the world but I have little context to go on and it is still more informative that the magic value 1000!

5/ Standard C++ library names are in namespace std:
Standard C++ names are now in the namespace std. This means that you need to qualify std when using such names. The name cout is one such example:


An alternative is to use a using declaration:

   using std::cout;

   // ...


A using declaration brings a single name into the current naming scope. It can be used locally in functions as well as outside functions.

Or if you really must a using directive:

   using namespace std;

   // ...


This should be used outside a function but after all headers have been included. It brings all known names of the given namespace into the current naming scope and is therefore a much more blunt instrument that a using declaration.

Note that such using declarations and directives should _never_ be used in a header file or before or during inclusion of header files in an implementation file. See Guru of the week ( number 53 ( as to why.

6/ Dynamically allocated memory and objects resources not released:
The nav array is not freed and the newly created object pointed to by ptr1 before it is re-assigned is not deleted. C++ and C do no garbage collection. The programmer is responsible for ensuring dynamically created objects are correctly deleted. In this case as it is just a small example it probably does not latter as modern desktop and server operating systems will clean up such resources at the end of execution as part of the process cleanup. In larger programs such leaks can be a problem, especially if they occur frequently or involve large amounts of memory.

OK, so now let's get down to the core of your problem:

  ptr.a=5;          // Line A

  ptr1=new test;          // Line B

  itoa(ptr.a,nav,10);      // Line C

  ptr1=(struct test*)nav;  // Line D

At line A you assign the full object ptr's a member a value of 5. This is the only mention of 5 in the program. Note that ptr is in no way related to the pointer to test variables ptr1 or ptr2.

At line B you use new to allocate memory for and create in that location a new test object. This object has a single member, a, that is _uninitialised_ - that is it contains random rubbish. This is because the type test has no constructors to perform initialisation of test objects and the default construction of built in types in such cases is to do nothing - hence they acquire a value based on the existing values at the memory locations they are allocated.

At line C you convert the rubbish value of ptr1->a to a sequence of characters and write them to the memory at nav.

At line D you use a sledge hammer C cast to effectively reinterpret (some of) the memory at nav as a struct test object and assign this value to ptr1. At this point you overwrite the previous pointer value ptr1 held and thus leak the original object pointed to by ptr1 created in line A as there is now no way to delete it. This memory contains a sequence of chars that represent the previous rubbish value of ptr1->a as digit characters. Assuming an ASCII based character set these values will be 0x30 ... 0x39 or 48 ... 57 in decimal, as these are the values that represent the digit characters 0 ... 9 in the ASCII character set. When placed into an int of probably 4 chars in size then the value will again be garbage to all intents and purposes.

A pointer in C and C++ can be considered as a value that represents a memory location. A pointer is aware of the type of the object it points to and thus a pointer to type X cannot be freely exchanged with a pointer to type Y if there is no relationship between X and Y as in this case (void * to char* and char* to test*). Information on the type pointed to is also used when performing arithmetic on pointer values - thus incrementing a pointer to char may change the pointer's value by 1 address location, whereas incrementing a pointer to int may change the pointer's value by 4 address locations (this assumes a byte sized char on a byte addressed machine in which an int is 4 bytes in size).

Defining an object and two pointers to objects of a given type implies no relationship between them. This is even more true if you start assigning different values to the pointers so they point to different objects - or even totally unrelated data forced to be taken as an object of that required type as you do here. At _no_ point in your example do you ever relate ptr1 with the (confusingly named) test object ptr. To do this you could have simply written:

   ptr1 = &ptr;
   std::cout << "ptr.a=" << ptr.a << "  ptr1->a=" << ptr1->a << '\n';

The & operator used in this context is the address of operator. That is, given an object (or reference to an object) of type T it returns a pointer to object type T that points to the object.

So my version of you code looks like so:

   #include <iostream> // required for std::cout

   struct test
   // Constructor:
   // ------------
   // Construct from single argument allowing member
   // a to be initialised at creation time.
   // A default argument value of 0 is used so that a
   // test object will be default initialised to zero.
   // The constructor is specified as explicit to prevent
   // the single argument constructor being used by the
   // compiler to implicitly convert an int to a test.
   // Note that an alternative to using a default argument
   // value is to use a separate default constructor:
   //  test() : a(0) {}

       explicit test( int value=0 )
       : a(value)

       int a;

   int main()
   // Object of type test initialised to 5.
       test testObject(5);

   // Pointer to test initialised to point to testObject
   // Note that on some compilers (e.g. MSVC 6.0) you may need to use:
   // test * testPtr = &testObject;
       test * testPtr(&testObject);

       std::cout << "testObject.a=" << testObject.a
         << "  testPtr->a=" << testPtr->a << '\n';

       return 0; // Required for broken compilers such as MSVC++ 6.0

Of course you may have been after some further insights into pointers. However from your example code and the brief accompanying text I am not sure what else exactly you are after. If you do need further advice then please post another question.

In any case I hope this has been of some help to you.  


All Answers

Answers by Expert:

Ask Experts


Ralph McArdell


I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.


My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at


©2017 All rights reserved.