zoukankan      html  css  js  c++  java
  • 【转】C++ Incorrect Memory Usage and Corrupted Memory(模拟C++程序内存使用崩溃问题)

    http://www.bogotobogo.com/cplusplus/CppCrashDebuggingMemoryLeak.php

    Incorrect Memory Usage and Corrupted Memory

    Here are the primary sources of the memory related problems.

    1. Using memory not initialized
    2. Using memory that we do not own
    3. Using more memory than allocated (buffer overruns)
    4. Using faulty heap memory management
    Accessing NULL pointer - invalid object
    访问空指针-无效对象

    When we try to access a method of an object using a NULL pointer, our program crashes.

    Here is a typical example of accessing an object with invalid pointer.

    #include <iostream>
    
    using namespace std;
    
    class A 
    {
    	int value;
    public:
    	void dumb() const {cout << "dumb()
    ";}
    	void set(int x) {cout << "set()
    "; value=x;}
    	int get() const {cout << "get()
    "; return value;}
    };
    
    int main()
    {
    	A *pA1 = new A;
    	A *pA2 = NULL;
       
    	pA1->dumb();
    	pA1->set(10);
    	pA1->get();
    	pA2->dumb();
    	pA2->set(20);
    	pA2->get();
    
            return 0;
    }
    

    Output from the run:

    dumb()
    set()
    get()
    dumb()
    set()
    

    We have three member function of a class A, "dumb()", "set()", and "get()". Pointers to A object are calling the methods of A. There is no problem calling those methods with properly allocated pointer pA1. However, the code crashes at the line:

    pA2->set(20); 
    

    Why?
    In the line, "set(20)" is invoked for a NULL pA2, it crashes when we try to access member variables of A class while there is no problem in calling "dumb()" with the same NULL pointer to the A object.

    Invoking a method with an illegal object pointer is the same as passing an illegal pointer to a function. A crash happens when any member variable is accessed in the called method. In other words, the "set(20)" tries to access a member variable "value" but "dumb()" method does not.

    If a pointer is a dangling pointer (pointing to memory that has already been freed), or to a memory location outside of current stack or heap bounds, it is referring to memory that is not currently possessed by the program. And using such pointer usually leads to a program crash.




    Dangling Pointer
    悬垂指针

    A dangling pointer arises when a code uses a memory resource after it has been freed as in the example below.

    struct X 
    {
    	int data;
    };
    
    int foo() 
    {
    	struct X *pX;
    	pX = (struct X *) malloc(sizeof (struct X));
    	pX->data = 10;	   
    	free(pX);
            ...	  
    	return pX->data;
    }
    

    The function "foo()" returns a member of struct X by using a pointer "pX" that has already released its memory. There is a chance that the memory block to which xp points has been overwritten with a different value. In the worst case, it may be deep into other places until it shows some symptoms. Dangling pointers are a constant source of headaches for C/C++ programs.



    Uninitialized Pointer
    为初始化指针

    Another common mistake is trying to access uninitialized memory as the example below.

    void fooA()
    {
    	int *p;
    	*p = 100;
    }
    

    Most of the implementation of compiler, this triggers "segmentation violation."

    As another example, the code below trying to free the pointer "p" which has not been initialized.

    void fooB()
    {
    	int *p;
    	free(p);
    }
    

    The outcome of this error is actually undefined, in other words, anything can happen.



    Deallocation Error
    释放错误

    Freeing a memory which has already been freed is another example of memory error.

    void fooA() 
    {
    	char *p;
    	p = (char *)malloc(100);	 
    	cout << "free(p)
    ";
    	free(p);
    	cout << "free(p)
    ";
    	free(p);
    }
    

    This type of error results in undefined behavior, it may crash or it may be passed unnoticed.



    Not calling derived class destructor
    ParentClass *pObj = new ChildClass;
    ...
    delete pObj;
    

    In the above example, coder's intention is do free the memory allocated for Child class object. However, because the type of "pObj" is a pointer to a Parent class, it deletes Parent object leaving the memory allocated for the Child object untouched. So, the memory leak.

    In this case, we need to use a virtual destructor to avoid this problem. The ~ParentClass() is called and then the destructor for Child class ~ChildClass() is called at run time because it is a virtual destructor. If it is not declared virtual, then only the ~ParentClass() is called leaving any allocated memory from the ChildClass to persist and leak.



    Buffer Overflow
    缓冲区溢出

    Depending on the length of the string, it may be attempting to write where the memory is not alloacted (void * memcpy ( void * destination, const void * source, size_t sz ).

    char *s = (char *)malloc(128*sizeof(char));
    memcpy(s, str, str_len);
    

    As another example, when we try to copy a string, we need to consider the null character at the end of the string.

    char *p = (char *)malloc(strlen(str));
    strcpy(p, str);
    

    In the code, we need to change the strlen(str) to strlen(str)+1.

  • 相关阅读:
    鸡哥的限币令(有上下限的网络流/费用流问题)
    AtCoder Regular Contest 128 部分题题解
    一道题
    2021CCPC河南省赛
    10.26训练赛
    博弈论和SG函数
    10.24训练赛
    10.22训练赛
    CF #749
    atcoder ABC233
  • 原文地址:https://www.cnblogs.com/MakeView660/p/8492277.html
Copyright © 2011-2022 走看看