0

When my input looks like this:

11

Harry Kate Fred Carol

My adjacency matrix should put Harry at [7][7], Kate at [7][10], Fred at [7][5], and Carol at [7][2]. However, Carol & Kate get inserted at other locations within the adj. matrix as well. I am guessing this has something to do with stack and heap memory, but I am not sure how to find the bug. Using cout statements, there doesn't appear to be any issues.

Code below

#include <iostream>
#include <string>
#include <stdlib.h>
#include <iostream>
#include <sstream>
using namespace std;

class Element {

public:
    string name;
    int weight;
    string color;

    //default constructor
    Element(void) {
        name = "";
        weight = 0;
        color = "white";
    }

    //parameterized constructor
    Element(string first) {
        name = first;
        weight = 0;
        color = "white";
    }

    void setBlack() {
        color = "black";
    }
};

class AdjMatrix {

public:
    int size;
    Element ***adj_matrix;
    AdjMatrix(void) {
        size = 0;
        adj_matrix = NULL;
    }

    AdjMatrix(int n) {
        size = n; //sets the size to n
        adj_matrix = new Element **[size];
        for (int i = 0; i < size; i++) {
            adj_matrix[i] = new Element *[i];
        }
    }

    //Destructor class
    ~AdjMatrix(void) {
        delete adj_matrix;
        adj_matrix = NULL;
    }

    //initialize the array with empty elements
    void initialize_matrix() {
        Element *add_element = new Element("");
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++)
                adj_matrix[i][j] = add_element;
        }
    }
};


int convertToASCII(string letter)
{
   int x = letter.at(0);
   int index = x - 65;
    return index;
};

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

    string table_size;
    cout<<"";
    getline(cin,table_size);
    int size = atoi(table_size.c_str());
    AdjMatrix *myGraph = new AdjMatrix(size);
    myGraph->initialize_matrix();

string line;
getline(cin, line);
while (getline(cin,line))
{
    if (line.empty())
        break;

    else {

        int x = convertToASCII(line);
        stringstream linestream(line);
        string temp;

        while (linestream >> temp) {
            int z = convertToASCII(temp);
            myGraph->adj_matrix[x][z] = new Element(temp);
        }
    }
}

//Print graph
for (int i = 0; i < myGraph->size; i++) {
    for (int j = 0; j < myGraph->size; j++)
        cout<<"["<<i<<"]["<<j<<"]: "<<myGraph->adj_matrix[i][j]->name<<endl;
}

  return 0;
}
3
  • when I run the program I receive the following output [7][2]: Carol [7][3]: [7][4]: [7][5]: Fred [7][6]: [7][7]: Harry [7][8]: [7][9]: [7][10]: Kate Is this not what you expect? Commented Apr 17, 2014 at 3:33
  • also, in initialize_matrix() you allocate multiple new Element("") and then later on in main() you say myGraph->adj_matrix[x][z] = new Element(temp); causing some memory leak. Commented Apr 17, 2014 at 3:39
  • In your output you will notice that Carol is also at [6][10] and Kate is at [8][0]. How would I otherwise initialize the array? I tried setting each location to NULL, but that crashes the program. Commented Apr 17, 2014 at 5:39

2 Answers 2

1

Your program has following problem which should be corrected.

 //default constructor
    Element(void) 

Constructor should be defined as

 //default constructor
    Element()
  • You should start using the std::vector for your 2D array. This would eliminate the manual memory management. We should avoid to use raw pointer in modern c++. Please refer the following SO post which describes how to use vector for 2D array.

two dimensional array using vector in cpp

Sign up to request clarification or add additional context in comments.

2 Comments

I am not allowed to use vectors in the assignment, otherwise I would have because they seem much easier to work with. I will be sure to make the change to the constructor.
You also have memory leaks. Look at your destructor -- do you think that a single call to delete will remove all of those allocations you made with new?. The class also doesn't follow the "rule of three", therefore your code is easily broken with a 3 line main() program.
0

In your AdjMatrix(int) ctor, you are constructing your triangular matrix (if that's what you're going for) incorrectly. Try this:

AdjMatrix(int n) {
    size = n; //sets the size to n
    adj_matrix = new Element **[size];
    for (int i = 0; i < size; i++) {
        adj_matrix[i] = new Element *[i + 1]; // Or size for a square matrix
    }
}

4 Comments

I tried this, but it causes the whole program to crash. Setting the first array to point to another array of the same size, creates a square grid, so that [0][0] is the first location not [0][1]
@OaklandFanatic - Please see this answer: stackoverflow.com/questions/23067857/c-deep-copy-object/… In there is a description of two ways of dynamically creating a 2d array. Just replace float with Element. Note how you create and destroy such arrays, something your current code fails to do (the destruction).
@OaklandFanatic If you want a square matrix, then put size where I put i + 1. Your error is that you have i there in your code.
@PaulMcKenzie thanks for the link. I had trouble trying to create a 2D array with a double pointer object but I will try this method again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.