0

I'll do my best to be brief: So I have an assignment where I am creating a 'Wordlist' class. In which I will store a list of words. These are the member variables

class WordList 
{ //...  
  unsigned int m_count;        // Number of words currently in list    
  unsigned int m_max;  // The total size of the list. 
  char** m_list;         // The list storing the words
};

This is my constructor

WordList::WordList(const int max_words) {
            
    if(max_words < 1){
        m_list = nullptr;
        m_max = 0;
        m_count = 0;
    }
    else
        m_list = new char*[max_words];
        m_count = 0;
        m_max = max_words;
    for (int i = 0; i < max_words; i++) {
        m_list[i] = new char[20];
    }
}

And this is where I start to find problems. The following add function is supposed to add a word in the form of a c-style string that is pointed to from the array of character pointers that is pointed to from **char m_list .

int WordList::add(const char word[]) {
    if (m_count == 0 && m_list != nullptr ) {
        strcpy (m_list[m_count], word);
        m_count++;
        return 0;
    }
    if (m_count < m_max) {
        m_count++;
        strcpy (m_list[m_count], word);
        return 0;
    }
    if (m_count == m_max) {
        m_count++;
        m_max ++;
        strcpy (m_list[m_count], word);
        return 1;
    }
    if (strlen(word)==0) {
        return -2;
      }
      if (m_list == nullptr ){
          return -2;
      }
else
    return -2;
}

So the issue I am having is that I clearly not syntactically correct with my * because I am not getting an array of 5 pointers that point to full words rather I am getting the first letter saved to the final destination char but its not copying over everything like I want.

I'm sure I didn't translate my problem to English as well as I should have but hopefully thats a start. Thank you!

An example of how I will be calling my add function:

WordList *wordlist = new WordList(5);
wordlist->add("harry"); 
wordlist->add("ron"); 
wordlist->add("hermione"); 

And it should add to the bottom of the pointer array a pointer to each word so

    cout  << wordlist->m_list[0][2] << endl; // Expect 'r'

    cout  << wordlist->m_list[1] << endl; // Expect "ron"

instead I get

r

printed out only

4
  • First, does the assignment allow you to use std::vector<std::string> as that would be a much better choice here. Second, please show us how you are calling the add() method. Commented Oct 12, 2020 at 2:16
  • 1
    Why do you think you're getting only the first letter? Can you provide a minimal reproducible example that shows the unexpected behavior? Also, unless your assignment doesn't allow it for some reason, just use a std::vector<std::string>. Commented Oct 12, 2020 at 2:16
  • " I start to find problems" --> strcpy (m_list[m_count], word); will have trouble if strlen(word) > 19. Commented Oct 12, 2020 at 2:19
  • Thank you for the quick responses I will post some more example code. Unfortunately I cannot use the string library at all. I think that is so that we really focus on manipulating pointers . Commented Oct 12, 2020 at 2:40

2 Answers 2

1

I don't see anything wrong with your use of double-pointers.

There are other issues, though:

  1. in your WordList::add you should check for empty word or empty list first, and fail fast. Besides, in your code if the word was empty - you would already added it and returned form that function.
  2. in if (m_count < m_max) block, you pre-increment m_count, leaving one element empty and risking to go out-of-bounds on the last entry.
  3. in if (m_count == m_max) { you are CERTAINLY going out-of-bounds
  4. Suggestion: instead of pre-allocating 20-character arrays, leave them nullptr; when you need to a word - use strdup(word); that would allocated a required space for you.
  5. As for your I am getting the first letter saved - I am guessing you are not checking it right...
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you so much for your help! I am looking over now and really appreciate it.
@StoneCodeStawny - yes, please see en.cppreference.com/w/c/experimental/dynamic/strdup
@StoneCodeStawny you can use realloc to resize your array: en.cppreference.com/w/c/memory/realloc . If there are new questions about that - yes, please create a new one.
@StoneCodeStawny Re: your printing code in the question - as I explained in my answer above, you are skipping element [1] because of your incorrect increments of m_count
@StoneCodeStawny realloc is as much C++ as strcpy :)
|
1

The problem is that you add the first word:

if (m_count == 0 && m_list != nullptr ) {
    strcpy (m_list[m_count], word);
    m_count++;
    return 0;
}

Which increments m_count so now m_count is 1.

Then you add the second word:

if (m_count < m_max) {
    m_count++;
    strcpy (m_list[m_count], word);
    return 0;
}

Which increments m_count BEFORE adding the word so the second word is at index 2 and index 1 is skipped altogether.

You need to always increment the count after copying the word because m_count is 1 based and the array is 0 based.

1 Comment

Wow sometimes it just takes another eye to catch something you are just stuck on. This has been so helpful!

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.