问题
I am trying to "initialize" an array that I have made in my class declaration and I do not know what I am doing wrong. I understand that when you pass an array into a function, it decays into a pointer to the first character. The code breaks on my second strcpy() line but I am not sure what it is I am doing wrong (I have very little experience with strcpy()).
My code reads as follows:
class TestClass
{
public:
TestClass(char []);
~TestClass();
void Append(TestClass);
char* m_string;
};
TestClass::TestClass(char incstring[])
{
char currentChar = 'a';
int numOfChars = 0;
while (currentChar != '\0') {
currentChar = *(incstring + numOfChars);
numOfChars++;
}
char* tmp = new char[numOfChars-1];
strcpy(tmp, incstring);
strcpy(m_string, tmp);
}
My int main() is simply:
int main(){
TestClass* test = new TestClass("Hello");
}
If it is worth noting, numOfChars is equal to 6, as it correctly should be.
The exception thrown is: " Access violation writing location 0xCDCDCDCD. "
回答1:
You are not allocating any memory for m_string
before you copy data from tmp
to m_string
. That is why you are crashing. m_string
is not pointing at a valid memory address.
Since you have already allocated tmp
and you are not going to use it anymore, you can just assign the tmp
pointer directly to m_string
without performing another copy.
Also, note that your while
loop is duplicating what strlen()
already does, so you should just use strlen()
.
Try this:
TestClass::TestClass(char incstring[])
: m_string(new char[strlen(incstring)+1])
{
strcpy(m_string, incstring);
}
TestClass::~TestClass()
{
delete[] m_string;
}
Which can be simplified using strdup()
instead (use free()
instead of delete[]
to deallocate it):
TestClass::TestClass(char incstring[])
: m_string(strdup(incstring))
{
}
TestClass::~TestClass()
{
free(m_string);
}
With that said, your main()
is leaking memory, as you are not freeing the test
object:
int main(){
TestClass* test = new TestClass("Hello");
//...
delete test; // <-- add this
}
Or simply:
int main(){
TestClass test("Hello");
}
And lastly, make sure you implement the Rule of Three in your class. You are managing dynamic memory that is freed in the destructor, so you also need a copy constructor and a copy assignment operation to ensure the integrity of m_string
when creating TestClass
values from other TestClass
values:
class TestClass
{
private:
char* m_string;
public:
TestClass(char *incstring = 0);
TestClass(const TestClass &src);
~TestClass();
void Append(const TestClass &str);
void Swap(TestClass &Other);
TestClass& operator=(const TestClass &lhs);
};
TestClass::TestClass(char *incstring)
: m_string(0)
{
if (incstring)
{
m_string = new char[strlen(incstring)+1];
strcpy(m_string, incstring);
}
}
TestClass::TestClass(const TestClass &src)
: m_string(0)
{
if (src.m_string)
{
m_string = new char[strlen(src.m_string)+1];
strcpy(m_string, src.m_string);
}
}
TestClass::~TestClass()
{
delete[] m_string;
}
void TestClass::Append(const TestClass &str)
{
if (str.m_string)
{
TestClass tmp;
tmp.m_string = new char[strlen(m_string)+strlen(str.m_string)+1];
strcpy(tmp.m_string, m_string);
strcat(tmp.m_string, str.m_string);
Swap(tmp);
}
}
void TestClass::Swap(TestClass &Other)
{
char *ptr = m_string;
m_string = Other.m_string;
Other.m_string = ptr;
}
TestClass& TestClass::operator=(const TestClass &lhs)
{
if (this != &lhs) {
TestClass(lhs).Swap(*this);
}
return *this;
}
来源:https://stackoverflow.com/questions/43531933/using-passed-in-array-to-initialize-other-array