C++ basic tutorial pointer copy details

  • 2020-05-12 02:58:28
  • OfStack

C++ basic tutorial pointer copy details

Pointers are a programmer's nightmare, for developers of the C language, and for developers of C++. In C++, in particular, it's easy to get into trouble if you don't pay attention to handling Pointers in your classes. If you don't believe me, here's the code:


class data 
{ 
 int* value; 
public: 
 data(int num){ 
 if(num > 0) 
  value = (int*)malloc(sizeof(int)* num); 
 } 
 
 ~data(){ 
 if(value) 
  free(value); 
 } 
}; 
 
void process() 
{ 
 data m(10); 
 data p = m; 
} 

Any questions about the question above? You can use a pen to draw 1 on the paper. Then on the machine with the actual environment to verify 1. Sure enough, the system tells you that an error has occurred in memory. Why is that? That's because the memory was freed twice. Let's take a look at the process assembly code:


21: data m(10); 
0040105D push 0Ah 
0040105F lea  ecx,[ebp-10h] 
00401062 call @ILT+15(data::data) (00401014) 
00401067 mov  dword ptr [ebp-4],0 
22: data p = m; 
0040106E mov  eax,dword ptr [ebp-10h] 
00401071 mov  dword ptr [ebp-14h],eax 
23: } 
00401074 lea  ecx,[ebp-14h] 
00401077 call @ILT+5(data::~data) (0040100a) 
0040107C mov  dword ptr [ebp-4],0FFFFFFFFh 
00401083 lea  ecx,[ebp-10h] 
00401086 call @ILT+5(data::~data) (0040100a) 
0040108B mov  ecx,dword ptr [ebp-0Ch] 
0040108E mov  dword ptr fs:[0],ecx 
00401095 pop  edi 
00401096 pop  esi 
00401097 pop  ebx 
00401098 add  esp,54h 
0040109B cmp  ebp,esp 
0040109D call __chkesp (004015b0) 
004010A2 mov  esp,ebp 
004010A4 pop  ebp 
004010A5 ret 

Line 21: data calls the constructor and allocates memory to value

Line 22: here we find that the program makes a memory copy, so the value of m variable value is the same as the value of value variable p

Line 23: this function is coming to an end, so the system call m and p destructor, first when the destructor value point to memory is released, the second time when the destructor due to the numerical non-zero value p variables, so also need to release the memory, of course, also need to be destructor processing, but memory has released at this time, so the memory release for a second time, the system error.

After the above research, we found the problem and the cause, so how to solve it? Since the problem is with the copy function, the copy function needs special treatment. As far as I know, there are two ways for you to choose:

(1) perform private processing on the copy constructor, so that once a copy operation occurs, the compiler will prompt for an error.


class data 
{ 
 int* value; 
 data(const data&) ; 
public: 
 data(int num){ 
 if(num > 0) 
  value = (int*)malloc(sizeof(int)* num); 
 } 
 
 ~data(){ 
 if(value) 
  free(value); 
 } 
}; 

(2) write a copy constructor to perform memory deep copy


class data 
{ 
  int* value; 
  int number; 
public: 
  data(int num){ 
    if(num > 0) 
      value = (int*)malloc(sizeof(int)* num); 
    number = num; 
  } 
 
  data(const data& d){ 
    if(NULL != d.get_ptr()) 
      value = (int*) malloc(sizeof(int)* d.get_number()); 
    number = d.get_number(); 
    memmove(value, d.get_ptr(), sizeof(int)* number); 
  } 
 
  ~data(){ 
    if(value) 
      free(value); 
  } 
 
  int* get_ptr() const{ return value;} 
  int get_number() const {return number;} 
}; 

We can see that after the definition of the copy constructor, the solution of the original process function can compile normally and pass without any problems.

Thank you for reading, I hope to help you, thank you for your support of this site!


Related articles: