C + + memory problem large set (pointer problem, and string copy problem, really dangerous)

Source: Internet
Author: User
Tags shallow copy sprintf

Author: rendao.org, copyright notice, reprint must obtain consent.

Memory out of bounds, variable tampered

Memset the length parameter exceeds the length of the array, but Memset did not error, but the operation of the memory should not be manipulated, causing the variable to be tampered with

Functions that can also cause memory out-of-bounds are memset, memcpy, Memmove, strcpy, strncpy, Strcat, sprintf, and so on

temporary pointer problem, std::string , Wstring the C_str () It's a temporary pointer .

The C_STR () return value is a char*/wchar_t* pointer, and the data for this array is temporary, and when a member function that changes the data is called, the data is invalidated. At this time, with Strlen, Wcslen, strcpy, wcscpy and other operations are unpredictable, the program will crash. Therefore, it is either converted first, or the data is copied to the memory that the user can manage.

String s= "1234″;

Const char* C = S.C_STR ();

This is a wrong way of writing. Because the repeated use of C-pointing content is actually very easy to invalidate.
Delete char* when the program crashes

1. Memory out of Bounds
char* newstr = new Char[strlen (S1) + strlen (S2) + 1];

sprintf (NewPath, "%s\\%s", S1, S2);

Then this newstr in the delete when the crash, because the open memory space is not enough, memory out of bounds, unable to accommodate the Terminator 0, if the strlen (S1) + strlen (S2) + 1 to strlen (S1) + strlen (s2) + 2 OK.

2. The deleted pointer does not belong to its own stack

If each DLL has its own heap for the heap, the memory that is allocated dynamically from the DLL is best removed from the DLL. If you allocate memory from a DLL and then delete it in an EXE or another DLL, it is likely to cause the program to crash. Also, the output error is invalid Address specified to Rtlvalidateheap.

3. Repeat Delete
Duplicate delete the same pointer will crash, sometimes difficult to find, one of the possible situations is that a class exists char* member (need new to open up memory), and this class is a shallow copy, if a copy between different objects A, B, a destroyed when the char* point to memory, B still think their char* The pointer is valid. Sometimes more secretive, you know there is a shallow copy of the matter is not enough, such as the occurrence of the copy is not necessarily your own code directly caused, such as Vector push_back operation will continue to cause the copy of the class object, and you do not understand the nature of push_back, you do not know that a copy occurred.

4, different projects use different run-time library settings
Specific phenomenon is the delete pointer when the program crashes, and output prompts invalid Address specified to Rtlvalidateheap, because the transfer of C + + between different modules (engineering) Class, and these two modules are set up with different runtime libraries (the Use runtime Library), C + +, Code Generation. For example: EXE module calls the DLL module to pass the C + + class function, DLL module use static link (Release is multi-threaded (/MT)  , Debug is  multi-threaded debug (/MTD) & nbsp;), while EXE module uses dynamic link (Release is  multi-threaded dll (/MD)  , Debug is  multi-threaded Debug DLL (/MDD) and nbsp;) mode compilation. You can compare the use Runtime library  of these two modules, and see if the settings are the same, and if not, change to the same one.

Above is the explanation on the network, and this reason may be related to the 3rd, may be due to the runtime library settings are different, resulting in invoking the method of the class of the other module, resulting in the heap ownership of the new memory belongs to a problem, so delete error. This paragraph is a simple guess, it may be wrong, but this problem has consumed a lot of time, seize it, practice proves that I used the same class (XSTR) in the EXE (Peer) and DLL (REG), and all the source code added to the project compiled, EXE new class object, the object pointer passed into the DLL , the DLL calls a method of the class (will be new memory) to accommodate the returned data, and this class object in the EXE does not destroy when there is a delete wchar_t* crash problem, prompted invalid Address specified to Rtlvalidateheap. Check the run-time library settings at this point, and find that it is indeed different, and as the online excerpt cited example, if the EXE and DLL in the settings are changed to multi-threaded dll/ multi-threaded Debug DLL, the problem is resolved.  multi-threaded and multi-threaded DLLs, the former refers to the use of multi-threaded version of the runtime library but static compilation, the latter difference is dynamic link.

On the meaning of the Use runtime library, Microsoft and C have two C run-time libraries, one common library of functions: LIBC.LIB, which does not support multithreading. Another type of support is Multithreading: MSVCRT.lib. If a project is mixed with these two libraries, it may cause this error, in general it requires MFC libraries to be linked before the C run-time library, so it is recommended to use msvcrt.lib that support multithreading. So before you use a third-party library, you first need to know what library it is linked to, or it may cause LNK2005 errors. If you have to use a third-party library, you can try to modify the method as described below, but there is no guarantee to solve the problem, the first two methods are provided by Microsoft: A, select the VC menu Project->settings->link->catagory Select Input , and then fill in the Edit column of ignore libraries you need to ignore the library, such as: Nafxcwd.lib; Libcmtd.lib. Then fill in the correct order of the libraries in the Edit column of object/library modules, where you can determine what is the correct order. (Best not to do so)

B, select the VC menu Project->settings->link page, and then enter/verbose:lib in the Edit tab of project options so that you can see the link order in the Output window during the compilation of the linker. C, select the VC menu project->settings->c/c++ page, catagory Select code generation after the user runtime Libraray select multithread DLL and other libraries, each Try.

5. The memory address indicated by the pointer is no longer the first address of new
char* p = new CHAR[10];
strcpy (P, "hello");
p++;
Delete p; Run to this back crash

Resolution of memory leaks

1. Find out if new and Delete,malloc/realloc/calloc/strdup and Free,virtualalloc and VirtualFree are paired

2, check whether the parentheses after the new char, because the use of parentheses, is to assign the initial value, the square bracket is the specified length. Debug may run out of bounds without immediate error, but the program will prompt for memory leaks when exiting. Of course, if it is release, the estimated execution of the program here will crash immediately.

3, sometimes, VC memory leaks hint line code in the new class object in the memory leak, and actually check that the class object is indeed the delete, in fact, the hint is not accurate
Possible 1: The actual discovery might not have been released for the class object new, but the code in the class object, including the new but not released in the called function, such as the call to Xml_inieasyget in new Cmysiteroot, and Xml_ Inieasyget calls only new not delete Charenc_strutf8toansi, which leads to memory leaks, but the error location is new Cmysiteroot
Maybe 2: It turns out that even the new location of the error may not have anything to do with it, at this time still obediently follow the steps to solve the method 1 to find, but faster, the basic affirmation is, follow step 1 to find, can always find the mismatch, not necessarily too believe that the VC output hint location

Ways to reduce the bounds of array read and write

Boost::array (check array subscript at debug, release is as efficient as normal array), smart pointer, vector

Memory leak, Cross check tool

Boundscheck, PageHeap, GFlags (windebug), Windebug

String Copy Note points

Be sure to pay attention to the Terminator, after the actual validation, strncpy, wcsncpy, memcpy, wcstombs and so on functions will only copy the specified number of characters, regardless of whether there is Terminator at the end, if you forget to fill the Terminator, may result in accessing this string when accessing someone else's memory oh.

Related Posts:
    1. Boost configuration (Vc/codeblocks) and compilation (BJAM+MSVC/MINGW)

tags:c++, Memory

http://rendao.org/blog/224/

C + + memory problem large set (pointer problem, and string copy problem, really dangerous)

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.