1

I'm trying to build an understanding of objects, arrays, and pointers. When I compile my code I ended up with 0xCCCCCCCC. I understand that this error is probably due to an uninitialized pointer. The problem is I don't know where or how to.

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
  string name;
};

void createPerson(Person* person[]);


int main() {

  Person* person[5];
  createPerson(person);

  for (int i = 0; i < 5; i++) {
    cout << person[i]->name << endl;
  }

  return 0;
}

void createPerson(Person* person[]) {
  string n[5] = { "Dwayne Johnson", "Connor McGregor", "SpongeBob","BatMan", "Ash Ketchum" };

  for (int i = 0; i < 5; i++) {
    person[i]->name = n[1];
  }
}

I'm trying to get the list of names to display.

kiner_shah
  • 3,939
  • 7
  • 23
  • 37
  • 4
    The value `0xCCCCCCCC` is typical for stack-allocated data (i.e. local variables) which isn't initialized. It means you're using a pointer that haven't been initialized. Like all the pointers in the `person` array. My advice: Don't use pointers, declare `person` as an array of `Person` *objects* (`Person person[5];`). – Some programmer dude Nov 05 '21 at 06:44
  • 1
    [0xCC means you're accessing uninitialized memory](https://stackoverflow.com/q/370195/995714) – phuclv Nov 05 '21 at 06:54

2 Answers2

1

The Problem is you have an Array of Person Person* person[] pointers and not an array of persons. I fixed the code and removed the pointers:

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
  string name;
};

void createPerson(Person person[]);


int main() {

  Person person[5];
  createPerson(person);

  for (int i = 0; i < 5; i++) {
    cout << person[i].name << endl;
  }

  return 0;
}

void createPerson(Person person[]) {
  string n[5] = { "Dwayne Johnson", "Connor McGregor", "SpongeBob","BatMan", "Ash Ketchum" };

  for (int i = 0; i < 5; i++) {
    person[i].name = n[i];
  }
}

As you can see I removed the pointer from your array definitions. This way the Person object gets initialized on the stack. In your way the pointers get initialized, but they dont point to anything. Thats why you get your error, because the pointers are dangling. If you really want to use an array of pointer you have to initialize these pointers like this:

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
  string name;
};

void createPerson(Person* person[]);


int main() {

  Person* person[5];
  createPerson(person);

  for (int i = 0; i < 5; i++) {
    cout << person[i]->name << endl;
    
    //delete person so that we dont leak mem
    delete person[i];
  }

  return 0;
}

void createPerson(Person* person[]) {
  string n[5] = { "Dwayne Johnson", "Connor McGregor", "SpongeBob","BatMan", "Ash Ketchum" };

  for (int i = 0; i < 5; i++) {
    person[i] = new Person();
    person[i]->name = n[i];
  }
}

BTW: I would not use pointers this way. If you are new and try to understand stuff its fine to experiment. But you should almost always use smart_pointers like std::shared_ptr etc. The next thing to experiment with should be containers and proper data structures.

Taron
  • 1,205
  • 2
  • 13
  • 29
  • Thank you for the explanation and feedback. So I need to allocate memories if I want to use an arrays of pointers? could you also explain the difference between -> and the dot operator? I noticed that your two solution uses two different (correct me if I'm wrong) accessor. – still_learning Nov 05 '21 at 08:19
  • The . Dot accesses the Object you Are using. The -> arrow accesses the Object which is pointed to. So in short you use the arrow when using pointers, iterators or smartpointer to objects and the Dot when using objects directly. – Taron Nov 06 '21 at 09:23
1

You are declaring an array of pointers of Person, but not initializing those pointers. By default, a pointer can point to some random location based on what garbage value is stored in its respective address (in this case 0xCCCCCCCC).

Solution is simple, just allocate a new memory using new keyword.

Also, since you are using new to allocate memory, you should call delete to de-allocate memory when you no longer require those pointers.

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
  string name;
};

void createPerson(Person* person[]);


int main() {

  Person* person[5];
  createPerson(person);

  for (int i = 0; i < 5; i++) {
    if (person[i] != nullptr)
        cout << person[i]->name << endl;
  }

  for (int i = 0; i < 5; i++) {
      if (person[i] != nullptr)
          delete person[i];
  }
  return 0;
}

void createPerson(Person* person[]) {
  string n[5] = { "Dwayne Johnson", "Connor McGregor", "SpongeBob","BatMan", "Ash Ketchum" };

  for (int i = 0; i < 5; i++) {
    person[i] = new Person();
    person[i]->name = n[i];
  }
}

In C++, you can use smart pointers instead of raw pointers also. See this

kiner_shah
  • 3,939
  • 7
  • 23
  • 37