in BufferArray::operator+, tempCharArray is a temporary buffer that will be destroyed when the function completes. There a basically two ways to handle this:
1/ allocate the temporary buffer with new[] in operator+, that way you'll make sure the buffer survives the call to operator+ but you'll either have a memory leak or require the caller to invoke delete[] later on, which is rather clumsy and error-prone
2/ or better yet, modify setBuffer so it does an internal copy of the buffer and add a call to delete[] in your own destructor :
BufferArray::~BufferArray() {
delete[] buffer;
}
void BufferArray::setBuffer(char *otherBuffer) {
buffer = new char[strlen(otherBuffer) + 1];
strcpy(buffer, otherBuffer);
}
Note that you'll have to modify the constructor so it also copies the input buffer (otherwise you'll have an illegal call to delete[] when the object is destroyed), and then you may want to overload the copy-constructor and assignment operator to prevent shallow copy which would result in double-deleting the buffer.
In actual production code, you'd want to use a managed pointer of some sort to avoid doing the delete yourself (e.g. std::vector or boost::shared_array), but for homework the above solution should be fine.
On a side note, don't forget to add +1 when using strlen to determine the size of your buffer ;)
Answer from ZeRemz on Stack OverflowHi all, I am trying to write a setter for a char array but getting into issues in the compilation side.
This char array of mine is used for ingesting in the name of a course.
In my header file, I have the following:
class Course
{
public:
Course(const char *name, unsigned credits);
void GetUnitName() const;
void SetUnitName(char* buf);
private:
char cName[10];
int cCredits;
};
inline void Course::GetName() const
{
cout << "Course name is: " << cName << endl;
}
inline void Course::SetName(char *input)
{
cName = input;
}I got the following error:
`error: incompatible types in assignment of 'char*' to 'char [10]'`
I tried several ways such as giving the defined size `char input[10]` however that fails badly too.
Can someone kindly guide me?
get and set char * - C++ Forum
How do I write setters and getters for an array? (c++) - Stack Overflow
getter and setter for array type - C++ Forum
Accessor (Getter) function for a c string (character array)
in BufferArray::operator+, tempCharArray is a temporary buffer that will be destroyed when the function completes. There a basically two ways to handle this:
1/ allocate the temporary buffer with new[] in operator+, that way you'll make sure the buffer survives the call to operator+ but you'll either have a memory leak or require the caller to invoke delete[] later on, which is rather clumsy and error-prone
2/ or better yet, modify setBuffer so it does an internal copy of the buffer and add a call to delete[] in your own destructor :
BufferArray::~BufferArray() {
delete[] buffer;
}
void BufferArray::setBuffer(char *otherBuffer) {
buffer = new char[strlen(otherBuffer) + 1];
strcpy(buffer, otherBuffer);
}
Note that you'll have to modify the constructor so it also copies the input buffer (otherwise you'll have an illegal call to delete[] when the object is destroyed), and then you may want to overload the copy-constructor and assignment operator to prevent shallow copy which would result in double-deleting the buffer.
In actual production code, you'd want to use a managed pointer of some sort to avoid doing the delete yourself (e.g. std::vector or boost::shared_array), but for homework the above solution should be fine.
On a side note, don't forget to add +1 when using strlen to determine the size of your buffer ;)
You need to use new to create these char arrays, otherwise the temporaries (like tempBA) are destroyed when you exit the scope.
void BufferArray::SetBuffer(char* buf)
{
buffer = new char[strlen(buf)+1]; //edit, my size param wasn't necessary
strcpy(buffer,buf);
}
string name[];
This is not an array, it is a pointer. Use vectors instead:
#include <vector>
class planet: public body
{
private:
vector<string> name;
vector<string> star;
public:
void nameSetter (const vector<string> &h_name)
{
name = h_name;
}
};
Arrays in C++ have compile-time fixed sizes. You can't have a declaration like string name[]; because it leaves the size empty. You can't do that unless you provide an initialization list from which the size is determined.
In addition, array type arguments are transformed to pointer arguments. So your string h_name[] argument is actually a string* h_name.
name[] = h_name[];
This line doesn't make much sense. It's almost like you're trying to access elements of name and h_name without giving an index. Perhaps you were intending to assign the h_name array to the name array, like so:
name = h_name;
However, as we've just seen, h_name is actually a pointer. And in fact, you can't assign to an array anyway, so even if h_name were an array, this still wouldn't work.
You'll be much better off using a standard container like std::vector. It appears that you want dynamically sized arrays anyway, so this will make that easy.
I'm still grasping the basics of the C language so I'll try to explain this the best I can. I have an array of char pointers and I can store a string literal to an element of the array.
For example:
char *array[256]; array[0] = "Hello";
What if I wanted to store a string literal to an element of array one character at a time?
char *array[256]; char *str = "Hello"; for (int i = 0; str[i] != '\0'; i++) array[0][i] = str[i];
The code above doesn't work, but what would be the correct way to about this?
Since the length of the name in your class is a fixed length, the easiest way to do this std::strncpy. That would work as follows:
inline void Unit::SetName (char const * name) {
std::strncpy(this->name, name, UnitNameSize);
// Ensure name member ends in null-terminator,
// even if new name length is >= UnitNameSize.
this->name[UnitNameSize - 1] = 0;
}
The error message is pointing to the fact that SetName's declaration and definition's signature does not match. In one you are expecting pointer to c string in the other a c string. Also, your SetName function is wrong, it would attempt to access the char pass the end of the string of the param. Why can't you use std:: string?
The short answer: A C compiler will bake constant strings into the binary, so you need to use strncpy (or strcpy if you aren't worried about security) to copy "{kernel}" into info[i].name.
The longer answer: Whenever you write
char label[] = "Single";
the C compiler will bake the string "Single" into the binary it produces, and make label into a pointer to that string. In C language terms, "Single" is of type const char * and thus cannot be changed in any way. However, you cannot assign a const char * to a char *, since a char * can be modified.
In other words, you cannot write
char label[] = "Single";
label[0] = "T";
because the compiler won't allow the second line. However, you can change info[i].name by writing something like
info[i].name[0] = '[';
because info[i].name if of type char *. To solve this problem, you should use strncpy (I referenced a manual page above) to copy the string "{Kernel}" into info[i].name as
strncpy(info[i].name, "{Kernel}", 256);
info[i].name[255] = '\0';
which will ensure that you don't overflow the buffer.
I think you may be mistaken. The way you would assign this would be one char at a time like so...
name[] = {'a','b','c','d'};