OK. I thought I understood pointers and such but this exercise is revealing that I do not. The task is to read characters into an array created on free store memory (heap), then print them out using the reference and dereference operators.
My code (below) compiles and runs but does not deliver the correct output. The value pointed to is special character like a playing card suit or a brace bracket. The address is the same for all the characters. The variable is not incrementing or it is always pointing to the first element of the array. I need help figuring out what is going on. Here is my code:

#include "../../std_lib_facilities.h"

int main ()
{
	char* ch = new char[10];
	char c = ' ';
	cout << "Enter characters separated by a space.\nUse the '!' to indicate the end of your entries." << endl;

	while (cin >> c) {
        if (c == '!') {
		break;
	} else {
		*ch = c;
		ch++;
		}
	}

	for (int i = 0; i < 10; i++) {
		cout << *ch << "  " << &ch << endl;
		ch++;
	}

	delete[] ch;

	keep_window_open();
        return 0;
}

Your incrementing your pointer (ch) as you populate your array and then you increment it it again to display the array and then you finally free your pointer...how does this not crash?

When you create you array on the heap save the initial pointer value like so:

char* ch = new char[10];
char *init_ch = ch;

Then use this initial value to set your pointer value back to its starting position.

i.e.

After you populate your array with values, please set

ch = init_ch;

and then run your for statement...when your done set

ch = init_ch;

then

delete [] ch;

Or you could try this way

#include <iostream>

using namespace std; 

int main ()
{
	char* ch = new char[10];
	
	for (int i = 0; i < 10; ++i)
		*(ch + i) = 'a' + i;

	for (int i = 0; i < 10; i++) 
		cout << static_cast<char>(*(ch + i)) << "  " << static_cast<void*>((ch + i)) << endl;

	delete[] ch;

        return 0;
}

Thank you, Gerard. You suggestions work perfectly. The code is below.

#include "../../std_lib_facilities.h"

int main ()
{
   char* ch = new char[10];
   char *init_ch = ch;
   char c = ' ';
   cout << "Enter characters separated by a space.\nUse the '!' to indicate the end of your entries." << endl;

   while (cin >> c) {
      if (c == '!') {
         break;
      } else {
	 *ch = c;
	 ch++;
      }
   }

   ch = init_ch;
   for (int i = 0; i < 10; i++) {
      cout << *ch << "  " << &ch + i << endl;
      ch++;
   }

   ch = init_ch;
   delete[] ch;

   keep_window_open();
   return 0;
}

When outputting the addresses of the characters, they increase by 4. So a char is given a size of 4 bytes. I thought a char was 1 byte in C++. Is my IDE (VC++) using 32 bit chars or is that the standard for C++? When I did an exercise on the use of the 'sizeof' operator, it yielded 1 byte for chars and bools.

Am I incrementing the address correctly or not?

>>Am I incrementing the address correctly or not?
No. The problem is that the expression "&ch + i" takes the address for the pointer "ch" and increments that address by "i". Now, the address of the pointer "ch" is a pointer to a pointer to a char, i.e. "char**". Since a pointer is a 32bit value (or 64bit on 64bit systems), when you increment the pointer to the pointer, it will increment it by 4 bytes.

>>Is my IDE (VC++) using 32 bit chars or is that the standard for C++?
A char is always of size 1, i.e. "sizeof(char) == 1" always, this is prescribed by the C++ standard. So even if, on some bizarre system, a char is stored with more or less than 8bits (1 byte), the "sizeof(char)" will still be 1. Say, for example, a system has chars of 16 bits, if "sizeof(int)" returns 4, it means that, on that system, an int is 64 bits long.

@ Mike,

How would I increment the pointer correctly? I want to print out the memory address of the next element in the array. I unsuccessfully tried ch. I am out of ideas at this point.

Thanks for your explanation.

Normally you should be able to do it like this:

ch = init_ch;
for (int i = 0; i < 10; i++) {
  cout << "character '"<< *ch << "' is at address " << ch << endl; //you don't need the "+ i" because ch is already getting incremented.
  ch++;
}

However, since "ch" is a pointer to char, the compiler will assume it is a pointer to a string (null-terminated sequence of characters) and will try to output all the characters until the null-character '\0'. To avoid that, you need to cast the pointer to a pointer of another type, like void for example:

ch = init_ch;
for (int i = 0; i < 10; i++) {
  cout << "character '"<< *ch << "' is at address " << reinterpret_cast<void*>(ch) << endl;
  ch++;
}

that should fix it.

Mike,

The chapter this exercise is in does have a section on void* and casts. I didn't read it closely and thoroughly the first time. After you posted, I re-read that section more closely. Stroustrup explained why we might need to ask the compiler to deal with pointers that point to objects of different types or unknown types. He also explains that we can convert a pointer from one type to another type using 'cast'. There is a very brief explanation of static_cast, reinterpret_cast, and const_cast.

I modified my program to include your suggestion and it ran correctly. I also used static_cast and that version ran correctly as well.

Stroustrup had an extended explanation of why using casts is a very bad idea (because they are 'buggy'). He stressed that it is always preferable to redesign a program so that the use of cast can be avoided. He concedes to using them only when it is unavoidable such as if dealing with other pre-existing code.

Your explanation was very clear and I feel fortunate that I have come to have a fairly good understanding of this topic. However, I am also glad that it is not something that is highly recommended.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.