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:
ReadFile
returns abool
in my version (notvoid
). Reading from a file may fail, and so it is better to returnfalse
to indicate an error.- 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.