• 【CPP】指针


    1- Pointers

    Pointers

    • A pointer is declared like a variable, but with * after the type
    • What stored in a pointer variable is an address.
    • Operator & can take the address of an object or a variable of fundamental types
    • Operator * can take the content that the pointer points to

    pointer.cpp

    #include 
    
    using namespace std;
    
    int main()
    {
        int num = 10;
        int * p1 = NULL, * p2 = NULL; // declaration, initialize to 0
        p1 = # // take the address of num, assign to p1
        p2 = # // take the address of num, assign to p2
    
        cout << "num = " << num << endl;
    
        *p1 = 20; // assign to num
        cout << "num = " << num << endl;
    
        *p2 = 30; // assign to num
        cout << "num = " << num << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    在这里插入图片描述

    Structure member accessing

    • p->member
    • (*p).member

    pointer-struct.cpp

    #include 
    #include 
    using namespace std;
    
    struct Student
    {
        char name[4];
        int born;
        bool male; 
    };
    
    int main()
    {
        Student stu = {"Yu", 2000, true};
        Student * pStu = &stu;
    
        cout << stu.name << " was born in " << stu.born 
             << ". Gender: " << (stu.male ? "male" : "female") << endl;
    
        strncpy(pStu->name, "Li", 4);
        pStu->born = 2001;
        (*pStu).born = 2002;
        pStu->male = false;
    
        cout << stu.name << " was born in " << stu.born 
             << ". Gender: " << (stu.male ? "male" : "female") << endl;
    
    
        
        
        return 0;
    }
    
    • 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

    在这里插入图片描述

    在这里插入图片描述

    Print out the address

    • Since the value of a pointer is an address, we can print it out
        printf("Address of stu: %p\n", pStu); //C style
        cout << "Address of stu: " << pStu << endl; //C++ style
        cout << "Address of stu: " << &stu << endl;
        cout << "Address of member name: " << &(pStu->name) << endl;
        cout << "Address of member born: " << &(pStu->born) << endl;
        cout << "Address of member male: " << &(pStu->male) << endl;
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • The address should be an unsigned 32-bit or 64-bit integer
        cout << "sizeof(pStu) = " << sizeof(pStu) << endl;
    
    • 1

    在这里插入图片描述

    Pointers of Pointers

    • Pointers are variables, they also have address

    pointer-pointer.cpp

    #include 
    using namespace std;
    
    int main()
    {
        int num = 10;
        int * p = &num;
        int ** pp = &p;
        *(*pp) = 20;
    
        cout << "num = " << num << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    在这里插入图片描述

    Constant Pointers

    const-pointer.cpp

    #include 
    using namespace std;
    
    int foo(const char * p)
    {
        // the value that p points to cannot be changed
        // play a trick?
        char * p2 = p; //syntax error
        //...
        return 0;
    }
    
    int main()
    {
        int num = 1;
        int another = 2;
        
        //You cannot change the value that p1 points to through p1
        const int * p1 = &num;
        *p1 = 3; //error
        num = 3; //okay
    
        //You cannot change value of p2 (address)
        int * const p2 = &num;
        *p2 = 3; //okay
        p2 = &another; //error
    
        //You can change neither
        const int* const p3 = &num;
        *p3 = 3; //error
        p3 = &another; // error
    
        return 0;
    }
    
    • 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

    const int *: 不可以修改指针指向的内容
    int * const: 不可以修改指针本身(地址)
    const int * const: 既不可以修改指针指向的内容也不可以修改指针本身

    const int * p;
    char * p2 = p;
    不能将const 的指针赋值给普通指针

    2- Pointers and Arrays

    • Use & operator to get the address of elements

    pointer-array.cpp

    #include 
    using namespace std;
    
    struct Student
    {
        char name[4];
        int born;
        bool male; 
    };
    
    int main()
    {
        // Part One
        Student students[128];
        Student * p0 = &students[0];
        Student * p1 = &students[1];
        Student * p2 = &students[2];
        Student * p3 = &students[3];
    
        printf("p0 = %p\n", p0);
        printf("p1 = %p\n", p1);
        printf("p2 = %p\n", p2);
        printf("p3 = %p\n", p3);
    
        //the same behavior
        students[1].born = 2000;
        p1->born = 2000;
    
        // Part Two
        printf("&students = %p\n", &students);
        printf("students = %p\n", students);
        printf("&students[0] = %p\n", &students[0]);
        
        Student * p = students;
        p[0].born = 2000;
        p[1].born = 2001;
        p[2].born = 2002;
    
        printf("students[0].born = %d\n", students[0].born);
        printf("students[1].born = %d\n", students[1].born);
        printf("students[2].born = %d\n", students[2].born);
    
        return 0;
    }
    
    • 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

    Array name

    • You can consider an array name as a pointer

    在这里插入图片描述

    Pointer arithmetic

    • p + num or num + p points to the num-th element of the array p
    • p-num points to the -num-th element

    在这里插入图片描述

    arithmetic.cpp

    #include 
    using namespace std;
    
    #define PRINT_ARRAY(array, n) \
    for (int idx = 0; idx < (n); idx++) \
        cout << "array[" << idx << "] = " << (array)[idx] << endl;
    
    int main()
    {
        int numbers[4] = {0, 1, 2, 3};
        PRINT_ARRAY(numbers, 4)
    
        int * p = numbers + 1; // point to the element with value 1
        p++; // point to the element with value 2
    
        cout << "numbers = " << numbers << endl;
        cout << "p = " << p << endl;
    
        *p = 20; //change number[2] from 2 to 20
        *(p-1) = 10; //change number[1] from 1 to 10
        p[1] = 30; //change number[3] from 3 to 30
    
        PRINT_ARRAY(numbers, 4)
    
        return 0;
    }
    
    • 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

    在这里插入图片描述

    • The following are equivalent
    int i = ...;
    int *p = ...;
    p[i] = 3;
    *(p  + i) = 3;
    int *p2 = p + i;
    *p2 = 3;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • Be careful of out-of-bound
    int num = 0;
    int * p = &num;
    p[-1] = 2;   // out of bound
    p[0] = 3;    // okay
    *(p+1) = 4;   // out of bound
    
    • 1
    • 2
    • 3
    • 4
    • 5

    bound.cpp

    #include 
    using namespace std;
    
    int main()
    {
        int a;
        int num = 0;
        int * p = &num;
    
        p[-1] = 2; //out of bound
        p[0] = 3; //okay
        *(p+1) = 4; //out of bound
    
        cout << "num = " << num << endl;
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    程序越界

    Differences between a pointer and an array

    • Array is a constant pointer
    • The total size of a ll elements in an array can be got by operator sizeof
    • sizeof operator to a pointer will return the size of the address (4 or 8)
    int numbers[4] = {0, 1, 2, 3};
    
    int * p= numbers;
    cout << sizeof(numbers) << endl;  // 4 * sizeof(int)
    cout << sizeof(p) << endl;  // 4 or 8
    cout << sizeof(double *) << endl;  // 4 or 8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3- allocate-memory: C style

    Program memory

    The address space of a program contains several data segments

    • Code: executable code
    • Data: initialized static variables
    • BSS: uninitialized static data including variables and constants
    • Heap: dynamically allocated memory
    • Stack: local variable, call stack

    在这里插入图片描述

    stack-heap.cpp

    #include 
    using namespace std;
    
    int main()
    {
        int a = 0;
        int b = 0;
        int c = 0;
        
        cout << &a << endl;
        cout << &b << endl;
        cout << &c << endl;
    
        int * p1 = (int*) malloc (4);
        int * p2 = (int*) malloc (4);
        int * p3 = (int*) malloc (4);
    
        cout << p1 << endl;
        cout << p2 << endl;
        cout << p3 << endl;
    
        free(p1);
        free(p2);
        free(p3);
    
        return 0;
    }
    
    
    • 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

    在这里插入图片描述

    • But different CPU architectures may be different

    Memory allocation

    • Allocate size bytes of uninitialized storage
    void* malloc(size_t size);
    
    • 1
    • Allocate 4 bytes and convert the pointer to (int *) explicitly
    int * p1 = (int *)malloc (4);
    
    • 1
    • Question:
    int * p1 = (int *) malloc(3);
    
    • 1

    pointer-convert.cpp

    #include 
    using namespace std;
    
    int main()
    {
        int * pi = new int[2]();
        unsigned char * pc = (unsigned char*)pi;
        pc[1] = 1;
        pc[5] = 2;
        cout << "pi[0] = " << pi[0] << endl;
        cout << "pi[1] = " << pi[1] << endl;
    
        delete []pi;
        //delete []pc; 
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    Memory deallocation

    • The dynamically allocated memory must be deallocated explicitly
    void free(void* ptr);
    
    • 1
    • Question:
    p = (int *) malloc (4 * sizeof(int));
    p = (int *) malloc(8 * sizeof(int));
    
    free(p);
    
    • 1
    • 2
    • 3
    • 4

    第一次申请的内存丢失了,无法管理也无法销毁

    void foo()
    {
        int* p = (int *) malloc( sizeof(int));
        return;
    } //memory leak
    
    • 1
    • 2
    • 3
    • 4
    • 5

    内存泄漏

    memory leak.cpp

    #include 
    #include 
    
    void foo()
    {
        int* p = (int *) malloc( sizeof(int));
        return;
    } //memory leak
    
    int main()
    {
        int * p = NULL;
        
        p = (int *) malloc(4 * sizeof(int));
        // some statements
        p = (int *) malloc(8 * sizeof(int));
        // some statements
        free (p);
        // the first memory will not be freed
    
        for(int i = 0; i < 1024; i++)
        {
            p = (int *) malloc(1024 * 1024 * 1024);
        }
        printf("End\n");
    
        return 0;
    }
    
    • 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

    在这里插入图片描述

    4- Allocate memory: CPP Style

    operator new and new[]

    • Operator new is similar with malloc() but with more features

    newdelete.cpp

    #include 
    using namespace std;
    
    struct Student
    {
        char name[4];
        int born;
        bool male; 
    };
    
    int main()
    {
        //allocate an int, default initializer (do nothing)
        int * p1 = new int; 
        //allocate an int, initialized to 0
        int * p2 =  new int();
        //allocate an int, initialized to 5
        int * p3 =  new int(5); 
        //allocate an int, initialized to 0
        int * p4 =  new int{};//C++11    
        //allocate an int, initialized to 5
        int * p5 =  new int {5};//C++11
    
        //allocate a Student object, default initializer
        Student * ps1 = new Student;
        //allocate a Student object, initialize the members
        Student * ps2 = new Student {"Yu", 2020, 1}; //C++11
    
        //allocate 16 int, default initializer (do nothing) 
        int * pa1 = new int[16];
        //allocate 16 int, zero initialized 
        int * pa2 = new int[16]();
        //allocate 16 int, zero initialized 
        int * pa3 = new int[16]{}; //C++11
        //allocate 16 int, the first 3 element are initialized to 1,2,3, the rest 0
        int * pa4 = new int[16]{1,2,3}; //C++11
    
        //allocate memory for 16 Student objects, default initializer
        Student * psa1 = new Student[16];
        //allocate memory for 16 Student objects, the first two are explicitly initialized
        Student * psa2 = new Student[16]{{"Li", 2000,1}, {"Yu", 2001,1}}; //C++11
        cout << psa2[1].name << endl;
        cout << psa2[1].born << endl;
    
    
    
        return 0;
    }
    
    • 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

    Operator delete and delete[]

    • Destroys object/objects allocated by new and free memory
        //deallocate memory
        delete p1;
        //deallocate memory
        delete ps1;
    
        //deallocate the memory of the array
        delete pa1;
        //deallocate the memory of the array
        delete []pa2;
    
        //deallocate the memory of the array, and call the destructor of the first element
        delete psa1;
        //deallocate the memory of the array, and call the destructors of all the elements
        delete []psa2;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    vx协议逆向原理
    Go语言中的Panic和高阶Func详细教程案例
    java和大数据开发该选择哪个好就业?
    知识点:PCB线路板布线都有哪些诀窍?
    ROS机器人应用(4)—— 查看里程计、IMU 话题信息
    Java 使用Lock、Condition的生产者与消费者问题(JUC)
    Pointnet/Pointnet++点云数据集处理并训练
    java虚拟机详解篇十一(java虚拟机栈)
    终于见到你了,中国天眼!
    C#开发的OpenRA游戏之信标按钮
  • 原文地址:https://blog.csdn.net/weixin_38362786/article/details/133906622