Fundamentals of Data Structure and Algorithm (Wang Zhuo) (8) Attachment: Detailed Explanation of How to Use New

Table of contents

part 1:

The usage of new in C++ (but just) is as follows (several usages):

1: new<data type>

2: new<data type>(<initial value>)

3: new<data type>[<number of memory units>]

Attached: part1

Attachment: part2

Part of the difference between not writing new and using new:

part 2:

part 3:


part 1:

The usage of new in C++ (but just) is as follows (several usages):

1: new<data type>

distribute:

The specified type, the size is 1, the memory space;

	int *i = new int;
	//注意!如果写:
	//int i = new int;
	//不行,会报错

2: new<data type>(<initial value>)

distribute:

The specified type, the size is 1, the memory space; initialize the variable with the value in parentheses

	int *i = new int(2);

3: new<data type>[<number of memory units>]

distribute:

The specified type, the size is (the number in the box) n, the memory space

Use the number n in the box: the size of the initialization space (number of array elements)

memory in the form of an array

	int* i = new int[5];
	char* i = new char[5];

Attached: part1

Define a multidimensional array variable or array object, yielding a pointer to the first element of the array

Returned type: holds all dimensions except the leftmost dimension

int *p1 = new int[10];   
return a pointer to int type int*  

int (*p2)[10] = new int[2][10]; 
returns a one-dimensional array pointing to int[10], pointer int (*)[10]

int (*p3)[2][10] = new int[5][2][10];     

Returns a pointer to a two-dimensional array int[2][10] of this type int (*)[2][10]

 But we need special reminders here (attention):

Here we no matter which of the above three situations

Variables on the left-hand side of an assignment statement in a new statement, no matter what:

This variable is, can only be, must be a pointer! ! !

And it's not like in the data structure behind us

Fundamentals of Data Structure and Algorithm (Wang Zhuo) (5): More complex operations on (single) linked lists_宇-Yu's Blog-CSDN Blog

As mentioned in it, the type of space opened up can have variables of this type directly on the left side of the assignment statement

Only pointers to that type can be placed on the left! ! !


original:

Points:

about

L= new Lnode;

In fact, I think it is really superfluous:

When the system started with the parameter LinkList &L, didn’t the memory space of L be allocated to you by default in advance? Why are you still working hard here?

In addition, where did the format of L= new Lnode; create space? ? ?

I have learned about the usage of new, only by defining pointers to allocate new space, like:

   Lnode* p = new Lnode;

But since it is available here, we also need to remember:

L= new Lnode;

Right now:

<First address of open space> = new <Data type of open space>

Format (remember to add auto if it has not been defined before)

Finally, after we went in-depth to learn about the usage and format of new, we found that this is not the case:

Not because it means L is a table, but there is a new format as we guessed

It is because the Linklist &L in front of the table header shows that it is originally a pointer and still belongs to the original usage specification

That is to say, if we have defined the variable before (when the formal parameter is passed), then when we open up space later

We don't (and can't) (re)declare the type of the variable


Attachment: part2

The general format of new dynamically creating a two-dimensional array in C++:

TYPE (*p)[N] = new TYPE [][N];

The type of p: TYPE*[N]; that is: a pointer to an array with N columns of elements

Without specifying the number of columns of an array (creates a two-dimensional array):

 int **p;

example:

	int **p = new int* [10]; 
	//int*[10]表示一个有10个元素的指针数组
	
	for (int i = 0; i != 10; ++i)
		p[i] = new int[5];


Part of the difference between not writing new and using new:

Pointer reception is necessary , initialized in one place and used in multiple places

As said earlier:

Variables on the left-hand side of an assignment statement in a new statement, no matter what:

This variable is, can only be, must be a pointer! ! !

Refers to what we are talking about here, the pointer used to receive

Need delete to destroy


new creates objects directly using heap space

And the partial does not use new to define the object to use the stack space


The new object pointer has a wide range of uses, such as function return values, function parameters, etc.


Frequent calls are not suitable for new, just like new application and release of memory

example:

Create objects with new: (pTest: used to receive object pointers)

	int* pTest = new int();
	delete pTest;

Create objects without new: (directly define with declaration)

	int mTest;

Create objects without new, and do not need to release them manually after use (write delete function)

Class destructors are automatically executed (release operations)

The object of the new application will only execute the destructor when the delete is called.

If the program exits without executing delete, it will cause a memory leak

Release the class pointer when creating an object with new:

	int* pTest = false;

If the class pointer has not been initialized by the object, it does not need to be deleted to release


part 2:

Data Structure and Algorithm Fundamentals (Wang Zhuo) (8): Application of Linear Tables

, you need to create a new table to return the result of the merge of the two tables (the final merged table):


1.1:

At the beginning, we thought very simply, that is, to use the actual parameters to pass back the new table:

int Merge(Sqlist A, Sqlist B, Sqlist& C)
{
    Sqlist* C = new Sqlist;

    //验证我们开辟空间出来以后的C
    //是一个线性表还是一个指针
    Sqlist D;
    D = C;

    return true;
}

But at this time, there is still a problem with the design of whether C is a linear list or a pointer to verify the space opened up:

Even if we delete the statement here to open up space

    Sqlist* C = new Sqlist;

Still does not affect the result of the last program run (success)


1.2:

Cancel the formal parameter linear table C, and verify whether the C we created separately is a pointer or a linear table:

int Merge(Sqlist A, Sqlist B)//, Sqlist& C)
{
    Sqlist* C = new Sqlist;

    Sqlist D;
    D = C;
}

result:

 This undoubtedly shows that the C of our new is a pointer, which still conforms to the basic format specification of the new statement we introduced earlier.

Therefore, if you want the program to run successfully (correct this error), you only need to change the assignment statement to:

    D = *C;

It can run correctly; note (remember):

The symbol added in front of C here must be "*", not "&"

We always habitually add "&" in front of the address, because we forgot:

& is the address-of operator

* is the value operator


2:

We can also directly set to return the merged table: (this way we don’t need to set an actual parameter to return the new table)

Sqlist Merge(Sqlist A, Sqlist B)
{
    Sqlist* C = new Sqlist;
    return *C;
}

3:

We have been writing function statements to open up space by ourselves before, but here we suddenly discovered:

We have written the initialized InitList() function before, so just write the initialization function directly:

int Merge(Sqlist A, Sqlist B, Sqlist& C)
{
    InitList(C);
    return true;
}


Of course, we can also handwrite the initialization statement according to (refer to) the definition of the initialization function we wrote earlier:

4.1:

The writing method of pointer passing value in the original InitList function: (pointer passing value)

int Merge(Sqlist A, Sqlist B, Sqlist *C)
{
    C.elem = (Poly*)malloc(MAXlength * sizeof(Poly*));
    if (!C.elem)
        exit(OVERFLOW);
    C.length = 0;
    return OK;
}

4.2:

The way of writing by reference in the original InitList function: (by reference)

int Merge(Sqlist A, Sqlist B, Sqlist& C)
{
    C.elem = new Poly[100]; //在堆区开辟动态内存
    if (!C.elem)//分配失败        
        exit(OVERFLOW);
    C.length = 0;
    return OK;
}

For a detailed explanation and analysis of each step of the initialization of the linear table, see:

Data Structure and Algorithm Fundamentals (Wang Zhuo) (2): Initialization of Linear Table_宇-Yu's Blog-CSDN Blog (End)


part 3:

new:

For details, see: C Language Diary 26 Pointers and Functions, Dynamic Storage Allocation_宇-Yu's Blog-CSDN Blog

Example 6-10 allocates space to store a two-dimensional array.

Source program:

#include <iostream>
using namespace std;
int main()
{
	int i, j;
	int** p;
	p = new int* [4];
	//开始分配4行8列的二维数据
	for (i = 0; i < 4; i++)p[i] = new int[8];
	for (i = 0; i < 4; i++)	//给二维数组放入数据
	{
		for (j = 0; j < 8; j++)p[i][j] = j * i;
	}
	//打印数据
	for (i = 0; i < 4; i++)
		for (j = 0; j < 8; j++)
		{
			if (j == 0) cout << endl;
			cout << p[i][j] << "\t";
		}
	for (i = 0; i < 4; i++)
		delete[] p[i];
	delete[] p;
	return 0;
}//1

result:

  here

    p = new int* [4];

What he wanted to express should be the so-called

    int(*p)[8];

This meaning, but the rules and specifications for opening up the second-level (dimensional) pointer space are not clearly stated in the book, such as:

    p = new int(*p) [4];

not work:

So, what are the rules and specifications for using the secondary (dimensional) pointer space of this multi-dimensional pointer type? !

When a multidimensional array variable or array object is defined using the new operator, it yields a pointer to the first element of the array

The returned type holds all but the leftmost dimension. For example:  

int* p1 = new int[10];

Open up a one-dimensional array and return an address (i.e. pointer) pointing to the int type storage space (int*)

int(*p2)[10] = new int[2][10];

Open up a two-dimensional array, (remove the leftmost one-dimensional [2], leaving int[10], so)

What is returned is an address (that is, a pointer) pointing to a one-dimensional array storage space such as int[10] (int (*)[10]) 


Next, we extend (extend) to three dimensions:

int(*p3)[2][10] = new int[5][2][10];

Open up a three-dimensional array, (remove the leftmost one-dimensional [5], leaving int[2][10], so) what is returned is a two-dimensional array storage space pointing to int[2][10] address (i.e. pointer) (int (*)[2][10]) 

The general format for dynamically creating a two-dimensional array with new in C++ is:

TYPE (*p)[N] = new TYPE [][N];

TYPE: type, N: the number of columns of the two-dimensional array.

With this format, the number of columns must be specified, but the number of rows need not be specified. Here, the type of p is TYPE*[N], which is a pointer to an array with N columns of elements.


There is another way to not specify the number of columns in the array: (this is the method we use here in this example)
 

    int** p; 
    p = new int*[10];  
    //Note that int*[10] represents a pointer array with 10 elements
    for (int i = 1; i <= 10; i++)p[i] = new int[5];

{

Array of pointers:

An array whose elements are pointers is an array in essence. (For example, int *p[3] defines three pointers p[0], p[1], p[2])

}

Here, the pointer name p of the secondary pointer **p is "int **" type (that is to say, it is a one-dimensional array storage space pointing to int[10] (like: int (*)[10]) address (i.e. pointer))

Specifically assigned to the secondary pointer **p pointer name p (one pointing to int[10]) one-dimensional array (one (10 elements) pointer array) type storage space address (ie pointer)).

We can easily notice that:

The "**p" here and our C language diary 25 (2) Supplement: Detailed explanation of the specific process of two-dimensional array and pointer understanding_宇-Yu's Blog-CSDN Blog (Inside: A[3][3], int **p=A; when executing p++, the compiler cannot use it because it cannot know the length (column width: how many columns are there in a row) The "(*p)[5]" mentioned in "(*p)[5]" and their pointer names represent a clear meaning different:

The array name p in (*p)[5] actually represents a row address

It is completely different from here: p also represents the first (element) address of the memory of the first (element) element of the entire two-dimensional array (row 0 of the entire two-dimensional array );

Of course, very similar to here, it represents a one-dimensional array, "[5]" means that the one-dimensional array contains 5 elements

And here, when opening the storage space, the array name p in **p represents the address of a one-dimensional array storage space


In addition, the program here (yes) cannot be changed to

    int(*p)[8];

form:

#include <iostream>
using namespace std;
int main()
{
	int(*p)[8];
	int i, j;
	p = new int* [4];
	//开始分配4行8列的二维数据
	for (i = 0; i < 4; i++)p[i] = new int[8];
	for (i = 0; i < 4; i++)	//给二维数组放入数据
		for (j = 0; j < 8; j++)p[i][j] = j * i;
	//打印数据
	for (i = 0; i < 4; i++)
		for (j = 0; j < 8; j++)
		{
			if (j == 0) cout << endl;
			cout << p[i][j] << "\t";
		}
	for (i = 0; i < 4; i++)
		delete[] p[i];
	delete[] p;
	return 0;
}//1

result:

 Why?

In fact, the reason is very simple:

Because the p we use here is an array of pointers, not an array pointer;

{

Array pointer:

A pointer to an array address is essentially a pointer;

Array of pointers:

An array whose elements are pointers is an array in essence. (For example, int *p[3] defines three pointers p[0], p[1], p[2])

}


I don’t know what he’s doing. I feel that these two programs are exactly the same. As a result, the following program is full of errors after being input:

#include <iostream>
using namespace std;
int main()
{
	int i,j;
	p = new int* [4];
	int** p;
	//开始分配4行8列的二维数据
	for (i = 0; i < 4; i++)p[i] = new int[8];
	for (i = 0; i < 4; i++)	//给二维数组放入数据
	{
		for (j = 0; j < 8; j++)p[i][j] = j * i;
	}
	//打印数据
	for (i = 0; i < 4; i++)
		for (j = 0; j < 8; j++)
		{
			if (j == 0) cout << endl;
			cout << p[i][j] << "\t";
		}
	//开始释放申请的堆
for (i = 0; i < 4; i++)
	delete[] p[i];
delete[] p;
return 0;
}

Can anyone figure out what's going on? ? ?

The parenthesis part of the main() function is typed into Chinese input method..

numb

Guess you like

Origin blog.csdn.net/Zz_zzzzzzz__/article/details/128589494