concat char *

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

class myString {
	private:
		char * str;

	public:
		myString(){};
		myString(char *);
		~myString();
		int compare(myString);
		int length();
		char * get_string();
		char * substr(int, int);
		void append(myString);
};

myString::myString(char * _str) {
	str = _str;
}

char * myString::get_string() {
	return str;
}

void  myString::append(myString str2) {

	char *pt = str;

	while (*pt != '\0') {
		pt++;
	}

	char *pt2 = str2.get_string();
	while (*pt2 != '\0') {
		*pt = *pt2;
		pt++;
		pt2++;
	}

	*pt = '\0';

	return;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* main.cpp */
#include <iostream>
#include "myString.h"
using namespace std;

int main () {

	char word1 [] = "12U45647KD";
	char word2 [] = "12u45647KD";

	myString str1(word1);
	myString str2(word2);

	str1.append(str2);

	cout<<"after append, str1 = " << str1.get_string()<<endl;

	return 0;
}


I have the above myString class that is supposed to simulate the stl string. However, when I concat 2 char * together, I got "No source available for "libstdc++-6!_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc() at 0x6fcb6afb"" in eclipse. It looks some kind of memory violation to me. When I ran the code in debugger, I can see *str in str1 actually appends the *str in str2. Can anyone see what my issue is?

TIA
I think there is a problem with your append function. It looks like you declare a char* and initialize it by pointing to the private member which already has a size. When you try to append more chars past that end, you are over-writing memory you shouldn't be. What you might try instead it to use 2 char arrays to hold the separate strings and then use counter variables to count the length of each. Then, declare a char[] with the sum of the lengths (+ 1 for the '\0') and copy the actual chars to that array. Then copy the new array into 'str'. Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
myString&  myString::append(const myString& str2){

        char *pt = str;
        char *pt2 = str2.get_string();
        int pt_count = 0, pt2_count = 0;

        while (pt[pt_count] != '\0') {
                pt_count++;
        }

        while (pt2[pt2_count] != '\0') {
                pt2_count++;
        }

        char result[pt_count + pt2_count + 1];
        int i, j;

        for(i = 0; i < pt_count; i++)
        {
               result[i] = pt[i];
        }
        for(j = i; j < (pt2_count + pt_count); j++)
        {
               result[j] = pt2[j - i];
        }

        result[j] = '\0';

        str = new char[j];

        for(int k = 0; k <= j; k++)
                str[k] = result[k];

        return *this;
}


You will also need to change the class definition:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class myString {
	private:
		char * str;

	public:
		myString(){};
		myString(const char *);
		~myString(){};
		int compare(const myString&) const;
		int length(void) const;
		char * get_string(void) const;
		char * substr(const int, const int); // don't know if this one modifies 'str' or not
		myString& append(const myString&);
};

Just a note on member functions: if the function is going to change the value of the private members, it should return a reference to an object of the class (return *this;). Also, when passing parameters they should always be declared const unless you intend to change the parameter's value within the function. Member functions that do not change any of the private members should be declared const.
See if that works any better. It may not be the best way, but it works. I'm not an expert c/c++ programmer, but I am always looking for different ways to do things.
Last edited on
Thanks!! I didn't know when str1 was first created, it already has a size associated with it. This makes sense now because without the size, I will be overwriting things in memory that I shouldn't. I changed way my append() work and included

1
2
3
for (int x = 0; x <= i; x++) {
  str[x] = new_str[x];
}


it works now.

I have a few more questions. Before I had the above code, I was doing

 
str = new_str


This didn't work because I am assigning a char * to a char[] . However, is there a way to assign the char * to the address of new_str? I am trying to figure out if it is possible to not do the char copy.

Also, I see you have

 
int compare(const myString&) const;


What does the const do at the end?

Thanks
For the first question:
A 'char*' is a 'char[]'. The problem is you can't point the 'str' to the new local pointer within the function. That variable is destroyed when the function ends, and with it, its memory allocation. The only way I could get it to work was with actually 'newing' 'str' and copying the new string to it.


For the second question:
It guarantees that 'this' object will not be modified. Even though the function only takes one parameter, there are 2 instances of the object involved: 'this' and the object passed to the function. When comparing, generally you do not intend to change anything about either object, you just want to 'compare' them and return a new piece of data that somehow describes how they compare to one another. That is why the parameter is 'const' and the function is also 'const'. This way if within the function body you inadvertently try to modify either one, you will get a compile error. Sort of a 'self checking' mechanism in simple terms.
Last edited on
Topic archived. No new replies allowed.