what is happening



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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 #include<iostream>
#include<cstring>
using namespace std;
class second{
private:
char* text;
int count;
friend class first;
};
class first{
private:
second* ptr;
public:
first(){
ptr=new second;
(ptr->text)=new char[4];
(ptr->text)="NULL";
(ptr->count)=0;
}

first(char*t) {
ptr=new second; 
(ptr->text)=new char[(strlen(t)+1)];
(ptr->count)=1;
strcpy((ptr->text),t);}


void operator =(first &e)
{
if ((ptr->count)==1)
{delete[]   (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}

else if((ptr->count)>1)
{((ptr->count)--); ptr=e.ptr; (ptr->count)++;}

else{delete (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}
}

first(first& e)
{
if (ptr->count==1)
{delete[]   (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}

else if((ptr->count)>1)
{((ptr->count)--);ptr=e.ptr; (ptr->count)++;}

else {delete (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}
}

void show()
{cout<<(ptr->text)<<endl;
cout<<"the number of objects use this is:"<<(ptr->count)<<endl;}

~first(){
if((ptr->count)=1)
{delete[] (ptr->text);
delete ptr; }
else if ((ptr->count)>1)
{(ptr->count)--;}
else
{delete[] (ptr->text);
delete ptr; }
}};
int main(){
	first a,s("this is required");
	first d;
	a=d;
	a.show();
	system("pause");
	return 0;
}

can anyone tell me what is the problem
Last edited on
You must know something, for else you would not be asking. How does your problem manifest itself?

Btw, a compiler does warn about three statements in your code. The second is most likely a logical error:
 In constructor 'first::first()':
17:12: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
 In destructor 'first::~first()':
55:18: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
 In function 'int main()':
65:30: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
There's a memory leak here,
16
17
(ptr->text)=new char[4];
(ptr->text)="NULL";

The memory allocated at line 16 can never be accessed since the pointer is assigned a different value on line 17.

Perhaps you meant something like this
16
17
    ptr->text = new char[5];  // allow for null terminator
    strcpy(ptr->text, "NULL");

I just was in chapter 11(virtual functions)in(object oriented programing -robert lafrofe-) and I wanted to build my own program about copy constructor and (= overloading) but here it is the original program from the book and I just don't have any idea why mine is not working
because I am just abeginner and my programme take about 5 hours.

// strimem.cpp
// memory-saving String class
// overloaded assignment and copy constructor
#include <iostream>
#include <cstring> //for strcpy(), etc.
using namespace std;
////////////////////////////////////////////////////////////////
class strCount //keep track of number
{ //of unique strings
private:
int count; //number of instances
char* str; //pointer to string
friend class String; //make ourselves available
//member functions are private
//--------------------------------------------------------------
strCount(char* s) //one-arg constructor
{
int length = strlen(s); //length of string argument
str = new char[length+1]; //get memory for string
strcpy(str, s); //copy argument to it
count=1; //start count at 1
}
//--------------------------------------------------------------
~strCount() //destructor
{ delete[] str; } //delete the string
};
////////////////////////////////////////////////////////////////
class String //String class
{
private:
strCount* psc; //pointer to strCount
public:
String() //no-arg constructor
{ psc = new strCount("NULL"); }
//--------------------------------------------------------------
String(char* s) //1-arg constructor
{ psc = new strCount(s); }
//--------------------------------------------------------------
String(String& S) //copy constructor
{
psc = S.psc;
(psc->count)++;
}
//--------------------------------------------------------------
~String() //destructor
{
if(psc->count==1) //if we are its last user,
delete psc; // delete our strCount
else // otherwise,
(psc->count)--; // decrement its count
}
//--------------------------------------------------------------
void display() //display the String
{
cout << psc->str; //print string
cout << " (addr=" << psc << ")"; //print address
}
//--------------------------------------------------------------
void operator = (String& S) //assign the string
{
if(psc->count==1) //if we are its last user,
delete psc; // delete our strCount
else // otherwise,
(psc->count)--; // decrement its count
psc = S.psc; //use argument's strCount
(psc->count)++; //increment its count
}
};
////////////////////////////////////////////////////////////////
int main()
{
String s3 = "When the fox preaches, look to your geese.";
cout << "\ns3="; s3.display(); //display s3

String s1; //define String
s1 = s3; //assign it another String
cout << "\ns1="; s1.display(); //display it

String s2(s3); //initialize with String
cout << "\ns2="; s2.display(); //display it
cout << endl;
return 0;
}
thank you very much now its working ,but after I close the programme a file named dbgdel.cpp
appear and a yellow arrow on the line
1
2
            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

appear
what this mean
It looks like your program tries to delete the same block of memory more than once.

First, you need to fix the problems highlighted by keskiverto above.

Line 21:
 
first(char*t)
should be
 
first(const char*t)


Line 55 is an error:
 
if((ptr->count)=1)

the = operator is an assignment, it should be the == test for equality.

Also an object with a count of zero doesn't make sense, when nothing is using that object it should be deleted. Hence line 18 does not make sense
 
(ptr->count)=0;

count should have a value of 1, not 0.
now I have reached this stage
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 #include<iostream>
#include<cstring>
using namespace std;
class second{
private:
char* text;
int count;
friend class first;
};
class first{
private:
second* ptr;
public:
first(){
ptr=new second;
(ptr->text)=new char[5];
strcpy((ptr->text),"NULL");
(ptr->count)=0;
}

first(const char*t) {
ptr=new second; 
(ptr->text)=new char[(strlen(t)+1)];
(ptr->count)=1;
strcpy((ptr->text),t);}


void operator =(first &e)
{
if ((ptr->count)==1)
{delete[]   (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}

else if((ptr->count)>1)
{((ptr->count)--); ptr=e.ptr; (ptr->count)++;}

else{delete (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}
}

first(first& e)
{
if (ptr->count==1)
{delete[]   (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}

else if((ptr->count)>1)
{((ptr->count)--);ptr=e.ptr; (ptr->count)++;}

else {delete (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}
}

void show()
{cout<<(ptr->text)<<endl;
cout<<"the number of objects use this is:"<<(ptr->count)<<endl;}

~first(){
if((ptr->count)==1)
{delete[] (ptr->text);
delete ptr; }
else if ((ptr->count)>1)
{(ptr->count)--;}
else
{delete[] (ptr->text);
delete ptr; }
}};
int main(){
	first a,s("this is required");
	first t(s);//copy constructor don't work here
	first d;
	a=d;
	a.show();
	system("pause");
	return 0;
}



line 66 is a new line to test my copy constructor
 
first t(s);//copy constructor don't work here  

but it just didn't work
Also an object with a count of zero doesn't make sense, when nothing is using that object

This. In other words, recheck the overall logic of your program.


it just didn't work

When you say "does not work" and do not explain, does it allow us to answer "you code has an error" without further explanation?

Explaining the error in detail is an essential part of finding the solution. In order to explain thoroughly, you end up thinking every step in your code and probably learn to spot the actual problem too.


The indentation of your code is not very informative (IMHO). It is hard to see individual (member) functions and local scopes among lines of text.


Copy constructor creates/initializes an object, just like the other constructors. What do you delete there?
thank you very much
in the code
 
	first d(a);/////////////////////////////// 

I just didn't know that the copy constructor was the first constructor
I did believe that the non argument constructor take place first
but I built a normal function it's only purpose to use the copy constructor and nothing happened
1
2
void test(first  q,first  w)//////////////
{}

then I add bool variable and the non argument constructor and the one argument constructor
set it to false
and the copy constructor now can see if the object had met any constructor before him
and every thing now is working properly
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include<iostream>
#include<cstring>
using namespace std;
class second{
private:
char* text;
int count;
friend class first;
};
class first{
private:
second* ptr;
bool NEW;///////////////////////
public:
first(){
NEW=false;/////////////////////////
ptr=new second;
(ptr->text)=new char[5];
strcpy((ptr->text),"NULL");
(ptr->count)=0;
}

first(const char*t) {
NEW=false;//////////////////////
ptr=new second; 
(ptr->text)=new char[(strlen(t)+1)];
(ptr->count)=1;
strcpy((ptr->text),t);}


void operator =(first &e)
{
if ((ptr->count)==1)
{delete[]   (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}

else if((ptr->count)>1)
{((ptr->count)--); ptr=e.ptr; (ptr->count)++;}

else{delete (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}
}

first(first &e)
{
if(NEW ==false)///////////////////////////
{if ((ptr->count)==1)
{delete[]   (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}

else if((ptr->count)>1)
{((ptr->count)--);ptr=e.ptr; (ptr->count)++;}

else {delete (ptr->text); delete ptr; ptr=e.ptr; (ptr->count)++;}
}
else{ptr=e.ptr;(ptr->count)++;}////////////////////////
}

void show()
{cout<<(ptr->text)<<endl;
cout<<"the number of objects use this is:"<<(ptr->count)<<endl;}

~first(){
if((ptr->count)==1)
{delete[] (ptr->text);
delete ptr; }
else if ((ptr->count)>1)
{(ptr->count)--;}
else
{delete[] (ptr->text);
delete ptr; }
}};
int main(){
	first a("this is a test"),s("this is required");
	first d(a);///////////////////////////////
	void test(first,first);
	test(a,s);
	a.show();
	s.show();
	d.show();////////////////////////////////
	system("pause");
	return 0;
}
void test(first  q,first  w)//////////////
{}
... you can lead a horse to water ...
Indeed, but lets add more water:
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
#include<iostream>

class Foo {
public:
  Foo() {
      std::cout << "Default ctor\n";
  }

  Foo( int ) {
      std::cout << "ctor(int)\n";
  }

  Foo( const Foo & ) {
      std::cout << "Copy ctor\n";
  }

  ~Foo() {
      std::cout << "dtor\n";
  }
};

int main(){
  std::cout << "1.\n";
  Foo a {42};
  std::cout << "2.\n";
  Foo b( a );
  std::cout << "3.\n";
  return 0;
}

Produces:
1.
ctor(int)
2.
Copy ctor
3.
dtor
dtor

It should be rather clear that the only constructor that is called on line 26 is the copy constructor.

Now we get to:
1
2
3
4
5
6
7
class Foo {
  int bar;
public:
  Foo( const Foo & ) {
      // Q: what is the value of bar now?
  }
};

In http://stackoverflow.com/questions/3127454/how-do-c-class-members-get-initialized-if-i-dont-do-it-explicitly
For primitive types (pointers, ints, bool, etc), they are not initialized -- they contain whatever arbitrary junk happened to be at that memory location previously.


A: We do not know the value of bar.

One more time:
1
2
3
4
5
6
7
8
9
10
11
12
class Foo {
  bool bar;
  T * ptr;
public:
  Foo( const Foo & ) {
     if ( bar ) { // ERROR: bar has not been set yet, so could be either true or false
      if ( 42 == ptr->gaz ) { // ERROR, the ptr does not point to anything valid yet
        delete ptr; // ERROR, the ptr does not point to anything valiid yet
      }
    }
  }
};




Further reading:
http://en.cppreference.com/w/cpp/language/default_initialization
https://isocpp.org/wiki/faq/ctors
http://en.cppreference.com/w/cpp/language/initializer_list
http://en.cppreference.com/w/cpp/language/data_members
Topic archived. No new replies allowed.