Constructor with parameters makes program crash

Hello.
I wrote a constructor with parameter char * for a class, whose objects are much like strings. And the program aborted, when it came to the part in the main function, where I used this constructor.
What I found unusual is that it aborted not in a typical VisualStudio2008-way, but like a usual windows application (e.g. a video-game).

Here's the code, showing class, constructor and main function:

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
class FString
{
private:
	char *data;
	char *end;
	int size;
public: 
             FString(char * sample) 
	{
		int i=0; 
		while (*(sample+i)!='\n') // I assume that sample ends with '\n' - that helps me find the end
		{
				i++;
		}
		size=i;
		for (i=0; i<size; i++)
			*(data+i)=*(sample+i);
		end=(data+size-1); 
		
	}
}

void main()
{
             char *test; 
             SCANSTR(test);   //I use this function to input the string
             FString obj(test);  // and here the program crashes
}

So, does anyone have an idea- what's wrong with the constructor? :\
Last edited on
Wow, i've just added

data=new char[size];

after 15th line and now it works, but only if the length of sample is 7 symbols or less.
Last edited on
There are quite few things wrong with your code:
1. You don't allocate FString::data so this is the main reason why your program is crashing. Put data=new char[size]; in constructor (EDIT: you already did this)
2. C-style strings always end with '\0' (null) character but you are checking for '\n'
1
2
3
4
5
		int i=0; 
		while (*(sample+i)!='\n') // I assume that sample ends with '\n' - that helps me find the end
		{
				i++;
		}

Are you trying to get length of the string? There is an easer way to get length of a string with strlen() function:
int length_of_string=strlen(sample);

1
2
		for (i=0; i<size; i++)
			*(data+i)=*(sample+i);

You can use strcpy to copy strings: http://www.cplusplus.com/strcpy

3. You didn't put a semicolon in line 21 so your code shouldn't compile.
4. Line 23: You should use int main() instead of void main()

Last edited on
Thanks a lot for the answer. Semicolon in 21 was just a typo. I tried your advices from 2)
At first I rewrote my code like this:

1
2
3
4
5
6
7
8
	FString(char * sample)
	{
		int i=0; 
		size=strlen(sample);
		data=new char[size];
		strcpy (data,sample);
		end=(data+size-1); 		
	}


and then I tried this:

1
2
3
4
5
6
7
8
9
	FString(char * sample) 
	{
		int i=0; 
		size=strlen(sample);
		data=new char[size];
		for (i=0; i<size; i++)
			*(data+i)=*(sample+i);
		end=(data+size-1); 		
	}


When i run both of these variants, the program still crashes, if strlen(sample) > 7

Maybe I'm missing something. One more thing, can you post your SCANSTR function?
Sure. *My code's so ugly*

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void SCANSTR(char *& test, int & len)
{
	char a;
	int check=1;
	test=new char[];	
	int i=0; 
	do
	{	
		scanf("%c", test+i);		
		if (*(test+i)=='\n') 
		{
			check=0;			
		}
		i++;
	}
	while (check!=0);
	len=i-1;
}


I was ashamed of my SCANSTR so I rewrote it to what you see in this post.
Now program runs fine, except when strlen(sample)==8.
One more thing, that changed after I used string-functions: I found some garbage in *data, when printing it.
(edit: for some reason, size, defined as
size=strlen(sample);
equals 14. Which may be because I define sample as
sample=new char[]
and not as
sample=new char[certain_size] )
Last edited on
Your don't need SCANSTR function:

1
2
3
4
5
6
7
// your main function
int main()
{
             std::string test;
             getline(cin,test);
             FString obj(test.c_str());  
}

change FString(char * sample) to FString(const char * sample)
And don't forget to #include <string>
Thanks a lot. That works perfect, but I'd like to ask some questions.

1) Why is the argument of constructor "test.c_str()" and not just "test" ?
(edit: I`ve just read about c_str and as I understood, test.c_str ~ * test (if test would be char)
2) Is string variable the same, as char * ?
edit: The answer is probably 'no', so is there a way do something like this?
1
2
3
  std::string test;
  getline(cin,test);
 char * st = &test;


one more edit: I did it like
1
2
3
4
5
6
 std::string test;
 getline(cin,test);
 char *a;
 a = new char [test.size()];
 strcpy (a, test.c_str());
 FString obj(a); 


So, everything's clear now (the problem seem to be with SCANSTR function)
Last edited on
2) No, they are very different. string is a class designed for strig manipulation while char * is a pointer to some memory location which contains your string (aka C-Style strings)
You can find out more about C-style strings here: http://www.cplusplus.com/doc/tutorial/ntcs/
and about strong class here http://www.cplusplus.com/reference/string/string/

1) .c_str() returns C-Style string equivalent of std::string
http://www.cplusplus.com/reference/string/string/c_str/

EDIT You can delete line 4 from your second example - it does nothing.
Last edited on
That line was just another typo.
String seems to be very useful class.
Thank you one more time. Finally I'm done with this nasty constructor.
Topic archived. No new replies allowed.