The re-learning of the new Expression Caused by a program crash, a crash of the new expression

Source: Internet
Author: User

The re-learning of the new Expression Caused by a program crash, a crash of the new expression

1. Cause

One day, a colleague told me that the background service crashed when an uninitialized pointer was used to debug a transaction core of the company's products on windows. The sample code is as follows:

1 struct sample 2 {3 int * ptr_table [4] [4]; 4 //... other members 5}; 6 7 void test () 8 {9 sample * sample_ptr = new sample [10]; 10 for (int I = 0; I <4; I ++) 11 sample_ptr [0]. ptr_table [0] [I] = new int (I); 12 13 // objects in the sample_ptr array are assigned values based on the initialization data in the system, but not all objects have initialization data; 14 int * int_ptr = sample_ptr [0]. ptr_table [0] [0]; 15 if (int_ptr! = NULL) 16 {17 printf ("ptr1 = 0x % x \ n", int_ptr); 18 * int_ptr = 100; 19} 20 21 int_ptr = sample_ptr [1]. ptr_table [0] [0]; 22 if (int_ptr! = NULL) 23 {24 printf ("ptr2 = 0x % x \ n", int_ptr); 25 * int_ptr = 100; // crashed here! 26} 27}

 

Using Uninitialized pointers is a big taboo of c ++, but this code has not encountered any problems for about two years since the product was released. The only difference is that the release and running environment is linux, and the debugging environment is the windows environment that was recently configured. Debug the code in linux and windows respectively. It is found that the newly applied memory in linux is initialized to 0, but the newly applied memory in windows is not initialized.

 

Change the line sample * sample_ptr = new sample [10] to sample * sample_ptr = new sample [10] (), and the execution results of the two systems change to the same, both of which are initialized memory.

The problem arises:

(1) Why are the same code (new sample [10]) in different forms in two systems? Is it because of the memory allocation mechanism of the two systems or the class library?

(2) What is the difference between new sample [10] and new sample [10?

 

2. Research

 

In c ++, memory is generally applied for and released using new/delete. What are the differences between the following new methods?

 

1 int* p1 = new int;2 int* p2 = new int();3 int* p3 = new int(1);4 // define class A;5 A* p4   = new A;6 A* p5   = new A();7 A* p6   = new A[10];8 A* p7   = new A[10]();

 

When writing code at ordinary times, I will use it only after initializing a newly applied memory, such as p3 direct initialization or memset, therefore, we do not know the difference between new A and new.

 

According to section 5.11 [1] of c ++ manual,The new and delete ExpressionsNew A belongsDefault Initializing of Dynamically Allocated Objects(Default initialization of dynamically created objects), while new A () belongsValue Initializing of Dynamically Allocated Objects(Initialize the value of the dynamically created object ).

When the default initialization operation is performed, if the created object does not explicitly define the default constructor, follow section 2.3.4 [2]Variable Initialization RulesTo initialize the rules:

  • When the object is a built-in type, any variables defined in the function in vitro will be initialized with 0 (Global or static), and no variables defined in the function body will be initialized.
  • When the object is of the class type, the default constructor of the object is called.

When it is a value initialization operation, if the created object does not explicitly define the default constructor, the object is considered to be initialized.

 

The initialization logic corresponding to different new usage is summarized as follows:

  New New () New A (parameters)
A is A built-in type No initialization action

Initialize the value

If case A is of the int type, the initialization is 0.

Initialize the value. A is initialized to parameters.
A Is calss/struct

Call the default constructor. Whether the member in A is

Initialization depends on the implementation of the default constructor.

If the default constructor is defined, the custom default constructor is called.

Otherwise, the system calls the default constructor and initializes the values of the members in.

Call the User-Defined constructor of.

 

 

 

 

 

 

 

 

 

Therefore, the execution results of the above Code are:

  • P1 points to an uninitialized int space.
  • P2 points to an initialized int space and its value is 0.
  • P3 points to an initialized int space with the value 1
  • P4 points to instance A that calls the default constructor. Unless A's default constructor initializes members of A, all members of A are uninitialized variables.
  • P5 points to instance A that calls the default constructor. If A customizes the default constructor, the initialization of the member variable depends on the custom default constructor, otherwise, all member variables of A are initialized variables.
  • P6 and p7 point to the array of instance A that calls the default constructor. The execution result is the same as that of p4 and p5.

 

Back to the previous issue, the struct sample does not have a custom default constructor. According to the c ++ standard, the execution result of the new sample is that ptr_table in the sample will not be initialized. This is consistent on windows, but why is it initialized to 0 on linux? On stackoverflow, I found a similar question [3]. The answer is:"Memory coming from the OS will be zeroed for security reasons .... the C standard says nothing about this. this is strictly an OS behavior. so this zeroing may or may not be present on systems where security is not a concern". The operating system's security mechanism initializes the allocated memory when the user program applies for memory to prevent others from reading sensitive data, such as passwords, from the newly applied memory, it is precisely because of this linux feature that the program always obtains an initialized memory when applying for memory for the first time.

I have not found official instructions on this security mechanism on the Internet. Maybe it is because my search method is incorrect or I have not found any correct keywords, in addition, it is found that the memory requested during the running process is not always initialized memory, for example, the following code:

 1 int size = 10; 2 { 3     int * p1 = new int[size]; 4     for (int i = 0; i < size; i++) 5     { 6         p1[i] = i + 200; 7         printf("%d\t", p1[i]); 8     } 9     printf("\n");10     delete []p1;11 }12 13 {14     int * p1 = new int[size];15     for (int i = 0; i < size; i++)16         printf("%d\t", p1[i]);17     delete []p1;18 }19 printf("\n");

Execution result:

 

I hope you will be able to provide relevant information.

 

3. Summary

 

(1) the code in the project obviously does not comply with the c ++ code specification, and there will be a logical phenomenon of using Uninitialized pointers. I personally think that the initialization of variables should not rely on the implementation of the compiler or system, but should follow the c ++ standard or manually initialize the variable.

(2) For the class/struct type, if there is no custom default constructor, different new usages will produce different results. Pay attention to this when writing code in the future.

 

1: http://shouce.jb51.net/c++/0201721481/ch05lev1sec11.html

2. http://shouce.jb51.net/c++/0201721481/ch02lev1sec3.html#ch02lev2sec13

3: http://stackoverflow.com/questions/8029584/why-does-malloc-initialize-the-values-to-0-in-gcc

 

This article is original content. please correct me if there is any error

Address: http://www.cnblogs.com/morebread/p/4936441.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.