Access to attributes of a structure by means of references in C ++

2

I have a node structure that has the following form

   struct Node {
      bool word;
      int frecuencia;
      char c;
      Node* arr [ALPHABET];
    };

The problem is that when you print the word shows a series of garbage characters and then typical Segmentation fault, I would greatly appreciate your help.

Ok thanks for the help, to put you in context I am using a trie data structure, the program receives a string (prefix), goes to a search function that assigns the node where the last character of the string is, that node is I pass it to the auto complete function that what it does or should do is find all the string suffixes entered.

The parameter that happened to autocomplete on its first call comes from the search function.

  Node* act;
  search(&word[0], act);
  list<string> leftOver = autocomplete(act);

Here is the search function

bool search (char* word, Node* actual) {
  Node* cursor = root;
  int index;
  for (int i = 0; i < strlen(word); i++) {
    //hallar el indice del caracter en el alfabeto
    for (int j = 0; j < ALPHABET; j++) {
      if (tolower(word[i]) == chars[j]) {
        index = j;
        break;
      }
    }
    if (cursor->arr[index] == NULL) {
      actual = cursor;
      return false;
    }else {
      cursor = cursor->arr[index];
    }
  }

   actual = cursor;
   if (cursor->word) {
    cursor->frecuencia += 1;
    return true;
   }
   return false;
}

This is the auto complete function

list<string> autocomplete (Node* cursor) {
  list <string> words;
  Node* children [ALPHABET];

  if (cursor->arr != NULL) {
      memcpy(children, cursor->arr, sizeof(Node*[ALPHABET]));
  }else {return words;}

  for (int i = 0; i < ALPHABET; i++) {
    Node* child = children[i];
    if (child != NULL) {
      string word = "";
      word += child->c;
      if (child->word) {
          words.push_back(word);
      }

      list <string> leftOver = autocomplete(child);

      // cout << leftOver.size() << endl;
      if (leftOver.size() > 0) {
        for (int i = 0; i < leftOver.size(); i++) {
          words.push_back(word + leftOver.back());
        }
      }
    }
  }
  return words;
}
    
asked by Ronald Cardona Martinez 14.11.2016 в 05:41
source

1 answer

2

You are writing C ++ code, then the definition of Node :

typedef struct Node {
  bool word;
  int frecuencia;
  char c;
  struct Node* arr [ALPHABET];
} Node;

It should look like this:

struct Node {
  bool word;
  int frecuencia;
  char c;
  Node* arr [ALPHABET];
};

Note that C and C ++ are different languages and each one has its own characteristics ... in fact not everything you can do in C will be valid in C ++ and vice versa. The logical thing when programming in C ++ is that you make use of the C ++ own syntax, even if only for clarity and coherence with the rest of the code that you will find.

Because of what you say, the only possibility that the error occurs (unless there is something you did not count) is that you have a code like the following:

Node* cursor;
string word; // = ""; <--- La parte comentada sobra
word += cursor->c;
cout << word << endl;

And the reason for this problem is that cursor is a pointer that does not refer to a valid memory location.

The specific solutions to this problem are dependent on which contributions more information. However I will try to make some assumptions.

You can choose to use the variable by value:

Node cursor;
cursor.c = 'A';
string word;
word += cursor.c;
cout << word << endl;

Even if this code is embedded in a function you might have something such that:

void func(Node& cursor) // <--- Una referencia
{
  string word;
  word += cursor.c;
  cout << word << endl;
}

Node* miCursor = /* inicialización */
func(*miCursor);

The advantage of using references is that you prevent someone from calling the function with a null pointer. You basically move the error to the function call, which simplifies the debugging of errors:

Node* miCursor = nullptr; // nullptr es de C++11 y es más seguro que usar NULL o 0
func(*miCursor); // ERROR

And of course it does not matter if you use objects by value:

Node miCursor;
func(miCursor); // OK

However, in the end it all comes down to knowing what each variable stores, and in this case you have to make sure that cursor is pointing to a valid object under penalty of reading erroneous memory positions.

    
answered by 14.11.2016 в 09:53