Odd output from program when entering operator? - c++

I'm probably missing something obvious here. This is my code (I'm just learning true C++, and I want to get some practice):
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * value;
int len;
friend ostream & operator<<(ostream & os, String s);
public:
String();
String(const char * base);
~String();
String operator+(String s);
String operator*(int n);
int length();
};
String::String() {
this->value = new char[0];
this->len = 0;
}
String::String(const char * base) {
this->value = new char[this->len = strlen(base)];
strcpy(this->value, base);
}
String::~String() {
delete [] this->value;
}
int String::length() {
return this->len;
}
String String::operator+(String s) {
String n;
delete [] n.value;
cout << "Upon entering, I am: \"" << *this << "\"\n";
n.value = new char[this->len + s.len];
for(int i = 0; i < this->len; i++) {
n.value[i] = this->value[i];
}
for(int i = 0; i < s.len; i++) {
n.value[i + this->len] = s.value[i];
}
n.len = this->len + s.len;
cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";
return n;
}
String String::operator*(int n) {
String s;
delete [] s.value;
s.value = new char[this->len * n];
for(int i = 0; i < this->len * n; i++) {
s.value[i] = this->value[i % this->len];
}
cout << "String::operator* succeeded with new value = \"" << s << "\"\n";
return s;
}
ostream & operator<<(ostream & os, String s) {
return os << s.value;
}
int main() {
String s("Hello, world!");
cout << s << "\nLength = " << s.length() << "\n\n";
cout << (s + String("\n")) * 5;
return 0;
}
And the string initializes and displays correctly, but my output is really strange; it seems that upon entering the operator+, "Hello, world!" suddenly becomes "x%r"?
C:\Users\Ryan\Documents\My Dropbox\C++ Projects>strings
Hello, world!
Length = 13
Upon entering, I am: "x%r"
String::operator+(x%r,
) succeeded with new value = "x%r"
String::operator* succeeded with new value = "╚%r"
─

Try this:
ostream & operator<<(ostream & os, const String& s) {
return os << s.value;
}
otherwise your should define copy constructor for your String class.

You need to provide copy constructor and assignment operator.

There are a lot of problems with your code.
You are managing your own memory. You should avoid doing this if at all possible.
You are consitantly forgetting that strings have a null terminator. In order to accomodate the strin Hello, world! you need a char buffer that is 14 bytes, not 13.
You have a len member variable that does effectively the same thing as the strlen function, except for the inconsistent consideration of #1 above.
Your string class does not have a copy constructor, which results in wild pointers and eventually crashes.
Here is a refactoring of your code that pretty much works.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;
class String {
private:
char * value;
// size_t len;
friend ostream & operator<<(ostream & os, String s);
public:
String();
String(const char * base);
String(const String& rhs)
{
value = new char[strlen(rhs.value)+1];
strcpy(value,rhs.value);
}
~String();
String operator+(String s);
String operator*(int n);
size_t length();
};
String::String() {
this->value = new char[0];
}
String::String(const char * base) {
this->value = new char[strlen(base)+1];
strcpy(this->value, base);
}
String::~String() {
delete [] this->value;
}
size_t String::length() {
return strlen(value);
}
String String::operator+(String s) {
String n;
delete [] n.value;
cout << "Upon entering, I am: \"" << *this << "\"\n";
n.value = new char[strlen(value)+strlen(s.value)+1];
for(int i = 0; i < strlen(value); i++) {
n.value[i] = this->value[i];
}
for(int i = 0; i < strlen(s.value); i++) {
n.value[i + strlen(value)] = s.value[i];
}
n.value[strlen(value)+strlen(s.value)] = '\0';
cout << "String::operator+(" << *this << ", " << s << ") succeeded with new value = \"" << n << "\"\n";
return n;
}
String String::operator*(int n) {
String s;
delete [] s.value;
s.value = new char[(strlen(value)*n)+1];
for(int i = 0; i < strlen(value) * n; i++) {
s.value[i] = this->value[i % strlen(value)];
}
s.value[strlen(value)*n] = '\0';
cout << "String::operator* succeeded with new value = \"" << s << "\"\n";
return s;
}
ostream & operator<<(ostream & os, String s) {
return os << s.value;
}
int main() {
String s("Hello, world!");
cout << s << "\nLength = " << s.length() << "\n\n";
cout << (s + String("\n")) * 5;
return 0;
}

Related

overloading operator "=" for vectors with shared ptr c++

I'm trying to make a little game on c++ and I'm trying to overload the "=" operator. It is supposed to copy the game, and make the copy undependable. Looks like I'm doing something wrong with the memory or something like that, because when I try to print the copy it crashes. What am I doing wrong?
This is the overloading:
Game& Game::operator=(const Game& other){
std::vector<Pair> new_grid;
for(int i=0; i < other.grid_characters.size(); i++){
Character* character = other.grid_characters[i].character->clone();
std::shared_ptr<Character> character_shared_ptr(character);
Pair new_element( other.grid_characters[i].grid_point, character_shared_ptr);
new_grid.push_back(new_element);
}
this->height=other.height;
this->width = other.width;
this->grid_characters=new_grid;
return *this;
}
Overloading the "<<":
std::ostream& operator<<(std::ostream& os, const Game& game){
std::string grid_str_to_print;
for(int i=0; i < game.height; i++){
for(int j=0; j < game.width; j++){
GridPoint grid_point(i, j);
std::shared_ptr<Character> character = getCharacterAtPoint(game, grid_point);
if(character == nullptr){
grid_str_to_print += ' ';
} else {
grid_str_to_print += character->getCharSymbol();
}
}
}
char* output_grid = new char[grid_str_to_print.length() +1];
strcpy(output_grid, grid_str_to_print.c_str());
printGameBoard(os,output_grid, output_grid + grid_str_to_print.length() ,game.width);
delete[] output_grid;
return os;
}
And printing the board:
std::ostream &mtm::printGameBoard(std::ostream &os, const char *begin,
const char *end, unsigned int width) {
std::string delimiter = std::string(2 * width + 1, '*');
const char *temp = begin;
os << delimiter << std::endl;
while (temp != end) {
os << "|" << (*temp);
++temp;
if ((temp - begin) % width == 0)
os << "|" << std::endl;
}
os << delimiter;
return os;
}
This is the pair:
struct Pair {
GridPoint grid_point;
std::shared_ptr<Character> character;
Pair(GridPoint grid_point, std::shared_ptr<Character> character) :
grid_point(grid_point), character(character) {}
};
This is clone:
Character* Soldier::clone() const {
return new Soldier(*this);
}
This is the code in the main:
#include <iostream>
#include <cassert>
#include "Exceptions.h"
#include "Game.h"
using namespace mtm;
void example1() {
std::cout << "------example 2------" << std::endl;
Game g1(5,10);
g1.addCharacter(GridPoint(3,0), Game::makeCharacter(CharacterType::SOLDIER, Team::POWERLIFTERS, 20, 0, 3, 5));
Game g2 = g1;
std::cout << g1 << std::endl;
std::cout << g2 << std::endl;
std::cout << "Nice!" << std::endl;
}
int main() {
example1();
return 0;
}
There is no error returned and no messages whatsoever.

Segmentation fault after everything executes-dynamic memory allocation: c++

I am fairly new to dynamic memory allocation and am having trouble. I'm thinking the problem is within my allocation function but I could be wrong. Here is the MyString.cpp file.
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "MyString.h"
using namespace std;
MyString::MyString()
{
m_size = 0;
buffer_allocate(0);
}
MyString::MyString(const char * str)
{
m_size = strlen(str);
buffer_allocate(m_size);
for(int i = 0; i < m_size; i++)
{
m_buffer[i] = str[i];
}
}
MyString::MyString(const MyString & other_myStr)
{
m_size = other_myStr.size();
buffer_allocate(other_myStr.size());
for(int i = 0; i < other_myStr.size(); i++)
{
m_buffer[i] = other_myStr.c_str()[i];
}
}
void MyString::buffer_deallocate()
{
delete[] m_buffer;
m_size = 0;
}
void MyString::buffer_allocate(size_t size)
{
try
{
m_buffer = new char[size];
}
catch(bad_alloc& ex)
{
delete[] m_buffer;
}
}
MyString::~MyString()
{
buffer_deallocate();
}
size_t MyString::size() const
{
return m_size;
}
size_t MyString::length() const
{
return m_size - 1;
}
const char* MyString::c_str() const
{
char * arr = (char*) malloc(m_size + 1);
int i;
for(i = 0; i < m_size; i++)
{
arr[i] = m_buffer[i];
}
arr[i] = '\0';
return arr;
}
bool MyString::operator== (const MyString & other_myStr) const
{
for(int i = 0; (i < m_size) && (i < other_myStr.size()); i++)
{
if(m_buffer[i] != other_myStr.c_str()[i])
{
return false;
}
}
if(m_size != other_myStr.size())
{
return false;
}
return true;
}
MyString & MyString::operator= (const MyString & other_myStr)
{
buffer_deallocate();
buffer_allocate(other_myStr.size());
for(int i = 0; i < other_myStr.size(); i++)
{
m_buffer[i] = other_myStr.c_str()[i];
}
return *this;
}
MyString MyString::operator+ (const MyString & other_myStr) const
{
int length = this->size() + other_myStr.size();
char * temp = (char*)malloc(length);
int j = 0;
for(int i = 0; i < length; i++)
{
if(i < this->size())
{
temp[i] = m_buffer[i];
}
else
{
temp[i] = other_myStr.c_str()[j];
j++;
}
}
MyString rhs = MyString(temp);
return rhs;
}
char & MyString::operator[] (size_t index)
{
return m_buffer[index];
}
const char & MyString::operator[] (size_t index) const
{
return m_buffer[index];
}
std::ostream & operator<<(std::ostream & os, const MyString & myStr)
{
for(int i = 0; i < myStr.size(); i++)
{
os << myStr[i];
}
os << endl;
}
Like I said, the segmentation fault is happening after the entire program is being executed so my guess is that there is some memory leak issue. I appreciate the help in advance.
And here is the main function:
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include "MyString.h"
using namespace std;
int main(void)
{
MyString dft;
if(dft.size() == 0)
{
cout << "Successful Default c-tor" << endl;
}
MyString param("Successful Parameter c-tor");
MyString copy(dft);
cout << param;
MyString ms_size_length("Size and length test:");
cout << ms_size_length;
cout << "Size of MyString: " << ms_size_length.size() << endl;
cout << "Length of MyString: " << ms_size_length.length() << endl;
MyString ms_toCstring("C-String equivalent successfully obtained!");
cout << ms_toCstring.c_str() << endl;
MyString ms_same1("The same"), ms_same2("The same");
if (ms_same1==ms_same2)
{
cout << "Same success" << endl;
}
MyString ms_different("The same (NOT)");
if (!(ms_same1==ms_different))
{
cout << "Different success" << endl;
}
MyString ms_assign("Before assignment");
ms_assign = MyString("After performing assignment");
MyString ms_append1("The first part");
MyString ms_append2(" and the second");
MyString ms_concat = ms_append1 + ms_append2;
cout << ms_concat;
MyString ms_access("Access successful (NOT)");
ms_access[17] = 0;
cout << ms_access;
}
One problem that I noticed is:
m_size = strlen(str);
buffer_allocate(m_size);
That allocates one less than the number of characters you need. As a consequence, you end up not copying the terminating null character to the object's m_buffer.
I suggest changing the constructor to:
MyString::MyString(const char * str)
{
m_size = strlen(str)+1;
buffer_allocate(m_size);
strcpy(m_buffer, str);
}
PS I did not look for other problems in your code. There may be more, or none.

Assertion `str' failed

I am new bee for c++ . I got follow error when I override operator+ .
ConsoleApplication1.out: /root/projects/ConsoleApplication1/sdstring.cpp:43: static sdstring::size_t sdstring::strlen(const char*): Assertion `str' failed.
This is my test code!
sdstring sd1(NULL);
cout << "sd1:" << sd1 << endl;
sdstring sd2("sd2");
cout << "sd2:" << sd2 << endl;
sdstring sd3;
cin >> sd3;
cout << "sd3:" << sd3 << endl;
sd3 +=sd2 ;
cout << "sd3:" << sd3 << endl;
sdstring sd4 =sd3+sd1;
cout << "sd4:" << sd2 << endl;
sd1 = sd2 + sd1;
cout << "sd1:" << sd1 << endl;
cout << "sd3==sd2:" << (sd3 == sd2)<<endl;
Error happened in This line .
sdstring sd4 =sd3+sd1;
This is my sdstring.cpp file.
#include "sdstring.h"
#include <assert.h>
sdstring::sdstring(const char *str) {
if (!str) {
datas = new char[1];
datas[0] = '\0';
}
else {
datas = new char[strlen(str)+1];
strcpy(datas, str);
}
}
sdstring::sdstring(const sdstring& str) {
datas = new char[strlen(str.datas) + 1];
strcpy(datas, str.datas);
}
sdstring& sdstring::operator+(const sdstring& str)const {
sdstring result(NULL);
size_t total_size = getlen() + str.getlen();
result.datas = new char[total_size + 1];
strcpy(result.datas, datas);
strcat(result.datas, str.datas);
return result;
}
bool sdstring::operator==(const sdstring& str)const {
return strcmp(datas, str.datas) == 0;
}
sdstring& sdstring::operator=(const sdstring& str) {
if (this == &str)
return *this;
delete[] datas;
datas = new char[str.getlen() + 1];
strcpy(datas, str.datas);
return *this;
}
sdstring::size_t sdstring::strlen(const char* str) {
assert(str);
size_t len = 0;
while ('\0' != *str++)
len++;
return len;
}
char* sdstring::strcpy( char* des, const char* src){
assert(des&& src);
char* temp = des;
while ('\0' != (*des++ = *src++));
return temp;
}
int sdstring::strcmp(const char* fir, const char* sec) {
assert(fir && sec);
while (*fir == *sec)
{
if (*fir == '\0') {
return 0;
}
++fir;
++sec;
}
return *fir - *sec;
}
char* sdstring::strcat(char* des,const char* src) {
char* temp = des;
while ('\0' != *des)
{
des++;
}
while ('\0' != (*des++ = *src++));
return temp;
}
sdstring::~sdstring()
{
if (datas)
{
delete[] datas;
datas = nullptr;
}
}
char& sdstring::operator[](const unsigned int position)const
{
return position < getlen() ? datas[position] : datas[position-1];
}
sdstring& sdstring::operator+=(const sdstring& str)
{
size_t total_size = getlen() + str.getlen();
if (total_size != getlen()) {
char* temp = datas;
datas = new char[total_size + 1];
strcpy(datas,temp);
strcat(datas, str.datas);
delete[] temp;
}
return *this;
}
ostream& operator<<(ostream& os, const sdstring& str)
{
os << str.datas;
return os;
}
istream& operator>>(istream& is, sdstring& str)
{
char* cache = new char[1024];
is >> cache;
delete[]str.datas;
str.datas = new char[sdstring::strlen(cache)];
sdstring::strcpy(str.datas, cache);
delete[]cache;
return is;
}
Who can help me , Thanks for first!
There are several things wrong with your code. However the operator + is wrong in that it is returning a reference to a local variable, which is undefined behavior.
sdstring& sdstring::operator+(const sdstring& str)const
{
sdstring result(NULL);
//..
return result; // Undefined behavior.
}
operator + should be returning a brand new object, not a reference to an object.
sdstring sdstring::operator+(const sdstring& str)const // <-- Note the return value is sdstring
{
sdstring result(NULL);
//..
return result;
}
The other issues with your code:
1) The operator= destroys the memory using delete[] datas; before calling new[] to allocate memory for the new string. If new[] throws an exception, the sdstring object would be corrupted since the data has been destroyed and you can't go back and reset the string with the old data. Use the copy / swap idiom to prevent this from happening.
2) You should store the length of the string in a member variable instead of calling strlen every time you want to know the length of the string. The strlen is slow in that it has to loop to count every single character to determine where the terminating '\0' character is located. Instead of that, just store the length of the string once and keep using that value.
3) Instead of writing your own strlen and strcmp functions, use the library functions strlen and strcmp. Your versions are not optimized, unlike the library versions.
4) operator + can be written in terms of operator +=. operator + should be written very simply as:
sdstring sdstring::operator + (const sdstring& rhs)
{
return sdstring(*this) += rhs;
}

Apply operator overriding to classes with dynamic allocation pointers

I have defined the MyString class, and now I want to implement the addition operation. It's horrible for memory leaks to occur, so I've taken care of releasing the dynamically allocated pointers from the destructor.
#include <iostream>
class MyString {
private:
int _size;
char* _str;
public:
MyString() {
_size = 0;
_str = nullptr;
}
MyString(int size, char* str) {
_size = size;
_str = new char[size + 1];
strcpy(_str, str);
}
~MyString() {
delete[] _str;
}
void print() {
std::cout << _str << std::endl;
}
friend MyString operator+(const MyString& lhs, const MyString& rhs);
};
MyString operator+(const MyString& lhs, const MyString& rhs) {
char* temp = new char[lhs._size + rhs._size + 1];
strcpy(temp, lhs._str);
strcat(temp, rhs._str);
MyString ret(lhs._size + rhs._size, temp);
delete[] temp;
return ret;
}
int main() {
MyString first(5, "first");
MyString second(6, "second");
MyString add = first + second;
first.print();
second.print();
add.print();
}
However, if I compile the code and run it, the first.print() and second.print() is printed well, but the add.print() will print the garbage value, and crashes (Debug Assertion Failed!).
Output:
first
second
硼硼硼硼硼硼硼硼?흚 (and creashes :(.. )
If I annotate and run the destructor, it prints well, but a memory leak occurs. Why is this happening? I have looked at several examples of operator overriding, but I have not found an example of this dynamic allocation of pointers.
Any suggestion will be highly appreciated!
MyString operator+(const MyString& lhs, const MyString& rhs) {
char* temp = new char[lhs._size + rhs._size + 1];
strcpy(temp, lhs._str);
strcat(temp, rhs._str);
MyString ret(lhs._size + rhs._size, temp);
delete[] temp;
return ret;
}
At the end of this function 'ret' is destroyed which calls the destructor and deletes the buffer. What is returned is a new instance of MyString that was copied from 'ret', and its buffer points to the same memory location as the original. Since this has been deleted you are now printing out garbage.
To fix this you can add a copy constructor to ensure the buffer is copied:
class MyString {
// Other class details
public:
MyString(const MyString & other) : MyString(other._size, other._str) {}
// Other class details
}
This will ensure the buffer is copied when one MyString is assigned to another MyString.
#include<iostream>
using namespace std;
class Mystring{
private:
int size;
char *str;
public:
friend Mystring operator*(const Mystring &a, const int &d);
friend Mystring operator+(const Mystring &a, const Mystring& b);
friend ostream& operator << (ostream &os, const Mystring a);
friend istream& operator >> (istream &is, const Mystring a);
Mystring (int a, char b) {
this->size = a;
this->str = new char(a);
for (int i = 0; i < a; i++) {
this->str[i] = b;
}
}
~Mystring() {}
};
Mystring operator+(const Mystring &a, const Mystring& b) {
Mystring c(a.size + b.size, { 0 });
for (int i = 0; i < a.size; i++)
{
c.str[i] = a.str[i];
}
for (int i = 0; i < b.size; i++)
{
c.str[a.size + i] = b.str[i];
}
return c;
}
Mystring operator*(const Mystring& a,const int &d){
int z = a.size*d;
Mystring c(z, { 0 });
int k=0;
for (int j = 0; j < d; j++)
{
for (int i = 0; i < a.size; i++)
{
c.str[k+i] = a.str[i];
}
k = a.size + k;
}
return c;
}
ostream& operator << (ostream &os, const Mystring a) {
os << "[";
int i;
for ( i = 0; i < a.size; i++)
{
os << a.str[i];
}
os << "]";
return os;
}
istream& operator >> (istream &is, const Mystring a) {
for (int i = 0; i < a.size; i++)
{
cout << i << "번째 문자 : ";
is >> a.str[i];
}
return is ;
}
int main()
{
int aSize, bSize, iter;
char aInit, bInit;
cout << "문자열A의 크기와 초기문자를 입력: ";
cin >> aSize >> aInit;
Mystring str1(aSize, aInit);
cout << str1 << endl;
cout << "문자열A 입력" << endl;
cin >> str1;
cout << str1 << endl;
cout << "문자열B의 크기와 초기문자를 입력: ";
cin >> bSize >> bInit;
Mystring str2(bSize, bInit);
cout << str2 << endl;
cout << "문자열B 입력" << endl;
cin >> str2;
cout << str2 << endl;
cout << "문자열A와 문자열B 합치기 : ";
Mystring str3 = str1 + str2;
cout << str3 << endl;
cout << "문자열A 반복횟수 입력 : ";
cin >> iter;
Mystring str4 = str1*iter;
cout << str4 << endl;
}
enter code here
why error
~Mystring(){}

String & String::Concat(const char Str[])

I decided to code all assignments from last semesters c++ class over summer in order to better prepare for c++ 3 but I don't understand how to pass through a String class or what steps are even needed in order to concatenate two strings and the display the result in the main cpp file.
In my Main.cpp:
#include <iostream>
using namespace std;
#include "String.h"
int main()
{
String Str1;
String Str2("this is a test");
String Str3(Str2);
String Str4("bruh");
int result;
cout << "Testing Display: " << endl;
Str2.Display();
cout << endl;
cout << "Testing displayLine: " << endl;
Str2.displayLine();
cout << endl;
result = Str2.Compare(Str3);
if (result < 0)
{
Str2.Display();
cout << " comes before " << endl;
Str3.Display();
cout << endl;
}
else
if (result > 0)
{
Str3.Display();
cout << " comes before " << endl;
Str2.Display();
}
else
{
Str3.Display();
cout << " is equal to " << endl;
Str2.Display();
}
cout << endl;
result = Str2.Compare("wxyz");
Str1.Copy(Str3);
cout << "Str1 contains " << Str1.length() <<" characters"<< endl;
cout << "Concatenation: ";
Str2.Concat(Str4);
cout << endl;
return 0;
}
In my String.cpp:
#include <iostream>
using namespace std;
#include <string.h>
#include "String.h"
#pragma warning(disable:4996)
String::String()
{
NumChars = 0;
MaxSlots = 0;
pChar = new char[NumChars+1];
pChar[0] = '\0';
}
String::String(const char Str[])
{
NumChars = strlen(Str);
pChar = new char[NumChars + 1];
strcpy(pChar, Str);
}
String::String(const String & Str)
{
NumChars = Str.NumChars;
pChar = new char[NumChars + 1];
strcpy(pChar, Str.pChar);
}
String::~String()
{
delete[] pChar;
}
int String::Compare(const String & Str) const
{
return strcmp(pChar, Str.pChar); //case sensitive
}
int String::Compare(const char Str[]) const
{
return strcmp(pChar, Str); //case sensitive
}
String& String::Copy(const String & Str)
{
if (this != &Str)
{
if (MaxSlots < Str.NumChars)
{
delete[]pChar;
MaxSlots = Str.NumChars;
pChar = new char[NumChars + 1];
}
else;
NumChars = Str.NumChars;
strcpy(pChar, Str.pChar);
}
else;
return *this;
}
String& String::Copy(const char Str[])
{
delete[] pChar;
NumChars = strlen(Str);
MaxSlots = NumChars;
pChar = new char[MaxSlots + 1];
return *this;
}
String& String::Concat(const String & Str)
{
pTemp = new char[NumChars+1];
strcpy(pTemp, pChar);
strcat(pTemp, Str.pChar);
delete[]pChar;
pChar = pTemp;
return *this;
}
String & String::Concat(const char Str[])
{
return *this;
/*
NumChars = strlen(Str);
MaxSlots = NumChars;
delete[] pChar;
MaxSlots = MaxSlots + NumChars;
NumChars = NumChars + strlen(Str);
pChar = new char[MaxSlots + 1]; */
}
void String::Display() const
{
cout << pChar;
}
void String::displayLine() const
{
cout << pChar;
}
In my String.h:
#ifndef STRING_H
#define STRING_H
class String
{
public:
String(); //default constructor
String(const char[]);
String(const String &); //copy constructor
~String();
int Compare(const String &) const;
int Compare(const char[])const;
String& Copy(const String&);
String& Copy(const char[]);
String& Concat(const String&);
String& Concat(const char[]);
void Display()const;
void displayLine() const;
int length() const;
private:
char * pChar;
char *pTemp;
int NumChars;
int MaxSlots;
};
inline int String::length() const
{
return NumChars;
};
#endif
You expect the length of the concatenated string to be the sum of the length of the two strings. Therefore:
String& String::Concat(const String & Str)
{
pTemp = new char[NumChars + Str.NumChars + 1];
strcpy(pTemp, pChar);
strcat(pTemp, Str.pChar);
delete[]pChar;
pChar = pTemp;
return *this;
}
You can optimize this further by not strcat()-ing but strcpy()-ing twice (with an offset added to pTemp second time), as you already know the string length.
I'm not sure to understand the use of your MaxSlots; it's the size of allocated pChar (minus 1)? If so, there are points in your code where you forget to set/update/use.
And I don't understand what do you mean with "how to pass through a String class", but regarding "what steps are even needed in order to concatenate two strings", you've forgotten to take in count the number of chars already present in the object.
First of all, I suggest to create e Reserve() method; something like [caution: code not tested]
String& String::Reserve (int n)
{
if ( n > MaxSlots )
{
MaxSlots = n;
pTemp = new char[MaxSlots+1];
strcpy(pTemp, pChar);
delete[]pChar;
pChar = pTemp;
}
}
Next, rewrite your Concat() methods in this way
String& String::Concat(const String & Str)
{
NumChars += Str.NumChars;
Reserve(NumChars);
strcat(pChar, Str.pChar);
return *this;
}
String & String::Concat(const char * Str)
{
if ( Str )
{
NumChars += strlen(Str);
Reserve(NumChars);
strcat(pChar, Str);
}
return *this;
}
p.s.: sorry for my bad English