penu
penu

Reputation: 1030

How to access array elements of pointers

How can I access elements from my Node pointer array? The cout at the bottom returns an address "0xb7738ff4". Even if I make a constructor and set each element to NULL, I cannot modify any of them later on.

#include <iostream>
using namespace std;

class Node
{
    public:
    char character;
};
class Tree
{
    public:
    Node* nodes[26];
};
int main() {
 Tree t;
 //t.nodes[0]->character = 'a';
 cout << "\"" << (t.nodes[0]) << "\"";
}

http://ideone.com/XvLme9

Upvotes: 0

Views: 76

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595320

t.nodes[0] is returning a Node* pointer. You are passing that pointer as-is to cout, that is why it is printing a memory address (and a random one at that, because you are not initializing the array). If you want to print the character of a node, you have to dereference the Node* pointer, exactly like your commented out code is doing (which is the correct way to do it):

t.nodes[0]->character

You just have to make sure that nodes[0] returns a valid pointer to a real Node object to begin with:

Tree t;
t.nodes[0] = new Node; // <-- here
t.nodes[0]->character = 'a';
std::cout << "\"" << t.nodes[0]->character << "\"" << std::endl;

Don't forget to delete the node when you are done using it. Tree should have a destructor that frees the nodes it owns.

Try something more like this:

#include <iostream>
#include <stdexcept>

class Node
{
public:
    char character;

    Node(char c = 0);
};

class Tree
{
private:
    Node* nodes[26];
    int count;
public:
    Tree();
    ~Tree();
    Node* add(char c);
    Node* get(int idx);
};

Node::Node(char c)
    : character(c)
{
}

Tree::Tree()
    : count(0)
{
    for (int i = 0; i < 26; ++i)
        nodes[i] = NULL;
}

Tree::~Tree()
{
    for (int i = 0; i < count; ++i)
        delete nodes[i];
}

Node* Tree::add(char c)
{
    if (count == 26)
        throw std::runtime_error("nodes array is at its max capacity");

    Node *node = new Node(c);
    nodes[count++] = node;
    return node;
}

Node* Tree::get(int idx)
{
    if ((idx < 0) || (idx >= count))
        throw std::out_of_range("invalid index");
    return nodes[idx];
}

int main()
{
    Tree t;
    t.add('a');
    std::cout << "\"" << t.get(0)->character << "\"" << std::endl;
}

With that said, you should use std::list or std::forward_list instead of writing your own tree class:

#include <list>

int main()
{
    std::list<char> l;
    l.push_back('a');
    std::cout << "\"" << l.front() << "\"" << std::endl;
}

Or:

#include <list>

class Node
{
public:
    char character;
    // other things here...

    Node(char c = 0);
    Node(const Node &src);
    Node& operator=(const Node &rhs);
};

Node::Node(char c)
    : character(c)
{ 
}

Node::Node(const Node &src)
    : character(src.character)
{
}

Node& Node::operator=(const Node &rhs)
{
    character = src.character;
    return *this;
}

int main()
{
    std::list<Node> l;
    l.push_back('a');
    std::cout << "\"" << l.front().character << "\"" << std::endl;
}

Upvotes: 2

Related Questions