Home > Mobile >  Dynamic Memory for Char pointer Array
Dynamic Memory for Char pointer Array

Time:05-17

I'm still very new to C , and I'm having issues with allocating heap memory. This is what I have in my header file:

const int NUM_WORDS = 1253;
const int CHAR_SIZE = 256;

class CWords 
{
public:
    // constructor(s)
    CWords();

    // destructor
    ~CWords();

    // public member functions
    void            ReadFile();
    const char*     GetRandomWord() const;


private:
    char*  m_words[NUM_WORDS]; // NUM_WORDS pointers to a char
    int    m_numWords;         // Total words actually read from the file
};

I'm trying to allocate space in the implementation cpp file, but I can't (default constructor):

CWords::CWords()
{
        m_numWords = 0;
        m_words = new char[strlen(m_words)   1];  // LINE 31
        strcpy(m_words, "NULL");    // LINE 32
}

line 31 gives me:

cannot convert 'char**' to 'const char*' for argument '1' to 'size_t strlen(const char*)'

and line 32 gives me:

cannot convert 'char**' to 'char*' for argument '1' to 'char* strcpy(char*, const char*)'

I don't know what these errors mean.

CodePudding user response:

The answer assumes that there is no strict requirement to force using C style arrays and strings.

As mentioned in the comments, even if you did manage the get rid of the bugs, this is not the recomended way to go in C .

std::vector is the go-to container if you need a dynamic size array. std::array is for a static size one. Also it is better to use std::string than C style strings. Doing so will save you the trouble of manual memory management (and the bugs that come with it).

Below is a modification of the header of your class:

#include <vector>
#include <string>

class CWords
{
public:
    // constructor(s)
    CWords();

    // destructor
    ~CWords();

    // public member functions
    bool                ReadFile();
    std::string const & GetRandomWord() const;

private:
    std::vector<std::string>  m_words;
};

I'll leave the implementation for you.

Notes:

  1. ReadFile returns a bool in my version (not void). Reading from a file may fail, and so it is better to return false to indicate an error.
  2. If you ever consider to inherit from class CWord, you'd better make the destructor virtual. See here: Should every class have a virtual destructor?.

CodePudding user response:

if m_words should represent multiple strings

In this case m_words is a static array with pointers pointing to several strings.
Hence it makes sense to initialize those pointers with NULL in your constructor (e.g. using a for loop for NUM_WORDS entries).
Beside that initialize the member m_numWords with 0. Obviously this member should contain the info how many entries of m_words are already filled.

if m_words should represent 1 string

Use char m_words[NUM_WORDS]; in your header file
then you don't need to dynamically allocate memory in the constructor (the memory is then part of every instance's size).

Or simply use a char* m_words; in your header file
and dynamically allocate as much chars as you need at a later time. This way you can free your string and allocate it with a different size whenever needed.
However in this case it is strongly recommended to initialize m_words with a NULL pointer in constructor.

Please also have a look at the strlen() description. It can only count the characters, that are already contained in your string.
Use sizeof() to measure the bytesize of static arrays.

  • Related