You are here:

C++/what could be wrong with my code?



please, when i compile and run this code, it crashes. i am guessing it has to do with with my constructor.. but not sure.. please, could you help me out on why?


using namespace std;

class Date{
     unsigned int day, month , year;
         Date(int d, int m, int y);
         void Show(){
         cout<<month << "/"<< day << "/"<<year<<"\n";
    Date::Date(int d, int m, int y){
         day = d;
         month = m;
         year = y;
         char *str;
         sscanf(str, "%d%*c%d%*c%d", &month, &day,&year);
     int main(){
         Date idata(12,31,99);
        return 0;

ANSWER: Yes it is:

       char *str;
       sscanf(str, "%d%*c%d%*c%d", &month, &day,&year);

Here are some hints:

What is a pointer?
What are automatic local variables such as str initialised to if you do not specify any initialisation value?
Where is the storage for the data read by sscanf?

That is what exactly does str point to?

What is a pointer?
Answer: It is merely a reference (a memory address value) to some other object or array of objects.

What are automatic local variables such as str initialised to if you do not specify any initialisation value?
Answer: Nothing.
They contain whatever was in the memory location(s) at the time they were allocated on the stack frame of a function call. That is for all intents and purposes an uninitialised local automatic variable (such as str) contains rubbish.

Where is the storage for the data read by sscanf?
Answer: it is at whatever location str refers to (see above answers - and hopefully you will see what is wrong)

What exactly does str point to?
Answer: Some random memory location.

So in short you are asking sscanf to read from some random and - as your program crashes - illegal - address because str is not initialised to point to any specific memory location that contains the date in character string form.

Further you should always check the returned value from sscanf and its family members - it will tell you how many values were parsed before a failure (or EOF). That is, if the returned value does not equal the number of items you expected to be read then something went wrong - most likely the string was badly formatted.

You seem to be trying to read from a C-style string (zero terminated array of char) representation of the date into the data members you have just initialised from the parameters of the constructor - eh?

Note: you can use C++ IOStreams to perform a similar action (using a std::string and a std::istringstream for example), but you would _still_ have to start with a string representation of the date!
So I think you need to decide first exactly what it is your constructor is supposed to be doing. Does it initialise from passed in values or does it initialise from a string (which should presumably be passed in instead of the d, m and y parameters).

If the latter then I suggest you look into using std::string to hold the string representation of the date and using std::istringstream to extract the components from it.

You can of course do both by providing 2 constructors:

   #include <iostream>
   #include <string>   // for std::string
   #include <sstream>  // for std::istringstream

   using namespace std;

   class Date
       unsigned int day;
       unsigned int month;
       unsigned int year;

       Date( int d, int m, int y )
       : day(d)
       , month(m)
       , year(y)

       Date( string const & dateString );

       void Show()
         cout<<month << "/"<< day << "/"<<year<<"\n";

I shall leave it up to you to find out how to implement the Date::Date( string const & dateString ) constructor.

You will notice the preferred initialisation style I have used in the Date::Date( int d, int m, int y ) constructor. This applies only to constructors and only base classes and data members can be initialised this way.

I have suggested you use a std::string because it behaves like a value - taking care of initialisation, resource (memory) management and release when done. That is it is a lot easier to work with than the raw C-style zero terminated arrays of char and the functions that work with them. Note: you can access the string as a read-only (i.e. const) C style string using the cstr() operation:


There should be tutorial and reference material around in book and online form e.g.:

As for a book I recommend "The C++ Standard Library a Tutorial and Reference" by Nicolai M. Josuttis.

If once you have tried to complete this class - if you feel it worth while at all of course - and come up against any further obstacles then please post a further question.

Hope this helps.

---------- FOLLOW-UP ----------


thanks. i get the idea. now, what then is the difference btween these:

char *str, *ptr;

*str = new char;
*str = "Ralph";

now suppose i want to pass the value of str to ptr, do i still have to initialise the ptr also?

which of these is correct then:

*ptr = *str;? //pass Ralph to ptr
ptr = new char;

*ptr = *str?


ANSWER: Wow! Nice to see someone actually using their brain.

So let us run through your examples and what is going on.

char *str, *ptr;
Declare and define 2 pointers to char named str and ptr.
If the statement appears within a function then these are local automatic variables and will not be initialised to any values.
If they are defined outside of a function then they will be global static variables and will be zero initialised.

Neither are very useful states for a pointer.

If you do need to set a 'not pointing to anything' value then use either NULL (C style) or 0 explicitly:

   char * str(NULL);   // initialise to null pointer C style
   char * ptr(0);      // initialise to null pointer C++ style

Note that the 0 value when used as a null pointer in C++ may not produce a pointer value whose bits are all zeros. The actual value used will depend on the platform in use - I think for example PRIME 50 series mini computers used a null pointer of 0400 (octal 400) or some such.

*str = new char;
This is _bad_ C++.

new char allocates memory for and default constructs a _single_ char object - which does no initialisation in the case of the built in types like char - on the free store (also called the heap) and returns a _pointer_ to the char.

You  use the * operator to _dereference_ the pointer to char called str - this removes one level of pointer-ness, hence *str refers to a char type and not a pointer to char type.

Thus you try to assign a pointer to char to a char, at some random or zero location, as indicated by whatever the initial value of str ended up being. Note that had you compiled this code you would have received errors about different level of indirection or some such - indirection as pointers refer to something indirectly.

You did not require the * in front of str - you use that when you wish to refer to what str points to rather than the pointer itself:

   str = new char;  // Good C++

Note: In C++ you are responsible for destroying and returning storage for such dynamically allocated objects using delete (or delete [] if you allocated an array of objects using new []):

// When done with current data pointed to by str:
   delete str;

*str = "Ralph";
First you made the same mistake as above, use just:

   str = "Ralph";

Secondly you have leaked the memory allocated by new char in the previous line as str was the only reference to that memory and you just overwrote it with a new pointer to the first character of a literal C-style string (a zero terminated array of char).

Strictly speaking the pointer to such literal string values is a pointer to a constant character, and usually a C++ compiler would complain if we assign it to a pointer to a non-constant char, as this would allow us to modify the literal. However it was OK to assign a pointer to non-constant char in C so C++ allows this exception for C compatibility.

*ptr = *str;? //pass Ralph to ptr
Nope - copy the value of the _single_ char at str as indicated by *str to the (unallocated memory at the rubbish/zero address) ptr as indicated by *ptr.

This is also bad C++, although it will compile it will not do what you want and will most likely crash - if you are lucky. If it does not then ptr has a value of some memory address that is accessible by the program's process and it will overwrite that location with 'R'. Good like finding which location got trashed - it probably would not show up for a while - at least in any program of any complexity, oh and of course it may well be that that byte were part of some larger value such as an int or double.

ptr = new char;
*ptr = *str
This, finally is correct, other than the missing semi-colon after = *str.


Allocate a new char, store a pointer to it as returned by new in ptr, then copy the _single_ char pointed to by str ('R') to that new char.

Again when you are done with the current char object pointed to by ptr it should be deleted:

   delete ptr;

You could of course have written:

   ptr = new char(*str);


So you have to be very careful when using pointers and values to ensure you know what you are pointing at and that you are in fact pointing to valid memory, and that you have consistent pointer / value 'levels of indirection' (note: you can have pointers to pointers, pointer to pointers to pointers etc.).

If you create new objects dynamically by using new then you should ensure they are destroyed when you are done with them using delete. If you use new [] to create an array of objects dynamically then ensure you use delete [] to delete them when done.

A char is _not_ the same as a string - a C-string or a C++ library std::string.

A C-string is no more than an array of char with the convention that the string is terminated using a character value of zero ('\0') - meaning the array needs one more elements than the maximum length of the string to store the terminating zero character.

In C and C++ there is _no_ way to automatically assign the contents of one array to the storage of another:

   char cstr1[]="12345";  // array char[6] - 5 for the contents and 1 for the '\0' terminator.
   char cstr2[6];

   cstr2 = cstr1;      // BAD not allowed

   char * pstr(cstr1);
   pstr = cstr1;       // OK but copies address of cstr1[0] to pstr, _not_ all characters of the string

Notice the C/C++ feature that using the name of an array yields the address of the first element of the array.

   pstr = new char[6];  // allocate space for 5 character C-string like cstr1
   *pstr = *cstr1;     // Copy '1', first character of cstr1 to first element pointed to by pstr.
   // ...
   delete [] pstr;     // Make sure we release resources pointed to by pstr.

Notice that to get enough storage for a copy of the whole of cstr1 we have to allocate a whole array of char using new [] and _not_ just a single char, and that it is released using delete [].

So in order to copy one array to another we need to copy each element explicitly using a loop:

   char str[]("12345");
   char *pStrCopy(new char[6]);
   char *pSourceStr(str);
   char *pDestinationStr(pStrCopy);
   while (*pSourceStr!='\0')
       *pDestinationStr++ = *pSourceStr++;

   // ...
   delete [] pStrCopy;

Notice that I do _not_ modify the original string array or pointer values directly - because you cannot for the array variable and I require the unmodified value of the pStrCopy pointer to use with delete [] to release the memory for pStrCopy when done with it.

The pointers used in the loop are initialised to the first char location of the source string, str and the destination string pStrCopy. The loop continues while the value at the source string location is _not_ the zero terminator. Each time around the loop the value at the current source string location is copied to the current destination string character location and each location is incremented to point to the next char.

Of course this sort of thing is quite tedious so the C library contains a set of functions for performing operations on zero terminated arrays of char style strings - declared in the C header <string.h>. C++ incorporated these functions, the header in C++ is called <cstring> - note the lack of a .h extension and the c prefix indicating it is from C.

The two functions that could be of use here are strlen and strcpy:

   #include <cstring>

   // ...

   char str[]("12345");
   char *pStrCopy(new char[strlen(str)+1]);

   strcpy(pStrCopy, str);

   // ...
   delete [] pStrCopy;

Of course we could just as well in this case calculated the number of elements required for pStrCopy using sizeof:

   char *pStrCopy(new char[sizeof(str)/sizeof(char)]);

In this case as sizeof(char) is by definition 1 we could just as well have written:

   char *pStrCopy(new char[sizeof(str)]);

But the previous form is useful for arrays of other types whose size is not directly apparent but known to the compiler:

   int data[] = { 1, 2, 3, 5, 7, 11, 13, 17, 19 };
   unsigned int numberofElements(sizeof(data)/sizeof(int));

Of course in the C-string examples we need not use dynamic memory or pointers directly at all:

   char str[]("12345");
   char strCopy[sizeof(str)];

   strcpy(strCopy, str);

Things get interesting when you are trying to do common string like things such as split apart strings, compose strings etc. when using fixed sized arrays - that maximum size always gets in the way, and can get lost if you do not make sure it is passed around, or you find yourself having to do lots of new [] and delete [] of dynamic strings with copying etc. just to keep track of the storage requirements as you go along.

This is why I suggested you look at using the C++ standard library std::string type (include <string>). It takes care of the storage management for you and leaves you to concentrate on doing the string like things directly:

   #include <string>
   // ...
   std::string str("12345");
   std::string strCopy(str);

   std::string anotherString("67890");
   std::string anotherCopy;

   anotherCopy = anotherString;

   std::string concatentatedString(str+anotherString);

   std::string anotherConcatentatedString;
   anotherConcatentatedString = str + anotherString;
   anotherConcatentatedString += "abcdef";

Hope this helps.

---------- FOLLOW-UP ----------

QUESTION: Hello Ralph,

i must admit i enjoy the short tutorial. itz good. here is what i was driving at.. i just scribbled dat in a hurry to get to you fast :)

char *str, *ptr;

str = new (char+1); //made a crazy mistake there.An extra 1 for the \0 guy
str = "Ralph"; // doesnt this initialisation allows the str pointer to  
         // point to the whole Ralph i.e index 0

after this initialisation, whatz in *str?

ptr = new char;

strcpy(ptr, str); // oh since this is only acceptable of arrays and

I enjoy the replies. keep it coming.. let me see whatz happening here..

thanks alot..

delete ptr, str; // never mind, should have separated dem..

my most important question is:

str = Ralph // points to the address occupying Ralph? am i correct?
*str = Ralph // points to 'R' right? so, how do i point to the full Ralph? i had thought all along that by doing this:

str = "Ralph";

First please take the time to write out your question(s) to me in an understandable fashion - I try hard to make sure my answers are as clear and understandable as possible - and no it does not take a short time to do so.

str = new (char+1)
This is rubbish.

(char+1) is meaningless. You cannot mix addition with a type.

You still have not appreciated the difference between scalar objects like a char and an array of many objects such as a C-string.  That is a string is a collection of zero or more characters - in C I suppose we would have to say it is an array containing 1 or more characters as an empty string ("") will be just the '\0' terminating character.

Note also that 'a' is different to "a". The former is a character literal, the latter a C-string literal and contains the characters 'a', '\0'.

str = "Ralph"; // doesnt this initialisation allows the str pointer to  
         // point to the whole Ralph i.e index 0
No. It points to the first character of "Ralph" - i.e. *str == 'R'.
the 'a', 'l', 'p', 'h' and '\0' characters occupy subsequent memory locations, which can be accessed by using the first character location as a base - either by changing the pointer directly or generating a new pointer from the original and an offset:

   char * str = "Ralph"; // sort of equivalent to: char astr[]={'R','a','l','p','h','\0'}; char * str=astr;

   char * a_ptr = str + 1;
   char * h_ptr = str + 4;

   ++str;      // str now points to 'a'
   str += 2;   // str now points to 'p'

ptr = new char;
strcpy(ptr, str); // oh since this is only acceptable of arrays and
Again you have failed to appreciate the difference between a single char - which holds a single character - and an array of char which can hold more than one character and forms the basis for strings in C.

   ptr = new char;
Allocates space for one and ONLY ONE character.

   strcpy(ptr, str);

Will copy the six characters of the C-string "Ralph" with the '\0' terminator pointed to by str to the allocated memory location at ptr and the FIVE FOLLOWING MEMORY LOCATIONS which are NOT allocated as part of the storage associated with ptr. That is you will trash 5 bytes of memory following that addressed by the value of ptr - which may well be part of the free store housekeeping, or maybe used for some other object.

strcpy DOES NOT magically allocate memory for use at the destination (i.e for use via ptr). It just copies all characters in the source (i.e. as pointed to by str) up to and including the '\0' terminator to the memory _starting_ with that at the destination address (i.e. ptr). If there is NOT ENOUGH memory allocated at the destination then strcpy WILL OVERWRITE whatever follows - which may or may not cuase a program crash - it is undefined behaviour.

str = Ralph // points to the address occupying Ralph? am i correct?
*str = Ralph // points to 'R' right? so, how do i point to the full Ralph? i had thought all along that by doing this:
No. Ralph is assumed to be an identifier not a string literal. The compiler has not seen a declaration (or definition which is also a declaration) for anything named Ralph so will raise an error.

However if what you really meant was:

str = "Ralph"; // points to the address occupying Ralph? am i correct?

Yes & no. str will be set to the address of the first character of the string literal that will contain the value 'R';

*str = "Ralph"; // points to 'R' right? so, how do i point to the full Ralph? i had thought all along that by doing this:

No. This is BAD C++. I say again. You did the same thing last time and I told you the same thing last time.
*str refers to the SINGLE CHARACTER occupying the memory at the address that is the current value of str.
"Ralph" is a string literal with the type char const *.
The two are incompatible.

You cannot squeeze the string "Ralph" into a single character location, especially as it is represented as the ADDRESS of the first character which is not a character at all.

So I say again, but louder:


C-strings are builtin arrays of characters.

OK this is not strictly true in C++ as you can wrap the array in a class which can be written to provide this single object like behaviour for instances of that class - as does std::string.

Now are you begriming to see the point here?

I think you really need to step back and consider very, very carefully all that I have told 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.