On C + + memory allocation and dynamic allocation of variable-length arrays _c language

Source: Internet
Author: User
Tags function prototype int size memory usage

First part C + + memory allocation

One. About memory

1. Memory allocation mode

There are three ways to allocate memory:

(1) Distribution from the static storage area. The memory is already allocated when the program is compiled, which exists throughout the running of the program.

such as global variables, static variables.

(2) created on the stack. When the function is executed, the storage units of local variables within the function can be created on the stack, and these save at the end of the function execution

The storage unit is automatically released. Stack memory allocation operations are placed within the processor's instruction set, which is highly efficient, but allocates a limited amount of memory.

(3) Allocation from the heap, also known as dynamic memory allocation. The program at run time with malloc or new request any amount of memory, the programmer from

You are responsible for releasing memory when free or delete. The lifetime of dynamic memory is determined by us and is very flexible to use, but the problem is the most.

2. Memory Usage Error

A memory error is a very troublesome thing to do. The compiler cannot automatically discover these errors, which are usually captured when the program is running.

Most of these errors do not have obvious symptoms, the hidden, increase the difficulty of error. Sometimes the user is angry to find you, the program is not

Any problem, you go, the mistake again attack. Common memory errors and their countermeasures are as follows:

* The memory allocation was unsuccessful, but it was used.

Novice programmers often make this mistake because they are unaware that memory allocations will be unsuccessful. A common workaround is to check before using memory

Whether the pointer is null. If you are using malloc or new to request memory, you should use if (p==null) or if (P!=null) for error proofing.

* The memory allocation was successful, but it was referenced without initialization.

There are two main causes of this error: one is the idea that there is no initialization; the second is to mistakenly assume that the default initial value of memory is zero, leading to the reference initial value

Errors (such as arrays). What is the default initial value of memory and there is no uniform standard, although sometimes zero value, we would rather believe that all

Believable it has. So no matter how you create an array, do not forget to assign an initial value, even if it is assigned 0 values can not be omitted, do not bother.

* The memory allocation was successful and initialized, but the operation crossed the bounds of the memory.

For example, when using an array, the subscript "more 1" or "less 1" is often taken place. Especially in the For Loop statement, the number of loops is easily mistaken, causing the array operation to cross over.

* Forgot to release memory, resulting in memory leaks.

A function that contains this error loses a piece of memory every time it is called. The system has plenty of memory at first, and you can't see the error. Once in a while

The program suddenly dies, the system prompts: the memory is running out.

Dynamic memory application and release must be paired, in the program malloc and free usage must be the same, otherwise there must be a mistake

(New/delete in the same vein).

* Freed up memory but continues to use it.

There are three kinds of situations:

(1) The object invocation relationship in the program is too complex to find out whether an object has freed up memory and should be

The design data structure, fundamentally solves the object management the chaos situation.

(2) The return statement of the function was incorrectly written, noting that the "pointer" or "reference" point to "stack memory" is not returned because the memory

The number of bodies is automatically destroyed at the end.

(3) When memory is freed with free or delete, the pointer is not set to null. Causes the "wild pointer" to be generated.

After rule 1 requests memory with malloc or new, you should immediately check that the pointer value is NULL. Prevent using memory with pointer value NULL

Rule 2 Do not forget to assign an initial value to an array and dynamic memory. Prevents unused memory from being initialized as a right value.

Rule 3 avoids the scaling of arrays or pointers, especially beware of "more than 1" or "less 1" operations.

"Rule 4" dynamic memory requests and releases must be paired to prevent memory leaks.

When rule 5 frees memory with free or delete, it immediately sets the pointer to NULL to prevent the "wild pointer" from being generated.

Two. Detailed New,malloc,globalalloc

1. New

The new and delete operators are used to dynamically allocate and revoke memory operators

New usage:

1> open a single variable address space

1) New int; Opens a storage space for the array, returning an address to the storage space. int *a = new

int assigns the address of an int type to the integer pointer A.

2 int *a = new int (5) acts as above, but at the same time assigns an integer value of 5

2> Open Array Space

One-dimensional: int *a = new INT[100]; Create an integer array space of size 100

General usage: new type [initial value]

Delete usage:

1> int *a = new int;

Delete A; Free space for a single int

2>int *a = new Int[5];

delete [] A; Frees int array space

To access the structure space opened by new, you cannot go directly through the variable name, only through the assigned pointer.

Use new and delete to dynamically open up and undo the address space. If you run out of a variable (typically a temporarily stored array) at the time of the program,

The next time you need to reuse, but you want to save the initialization of the Kungfu, you can start each time to open a space, after the use of the undo it.

2. malloc

Prototype: extern void *malloc (unsigned int num_bytes);

Usage: #i nclude <malloc.h> #i nclude <stdlib.h>

Function: Allocate a block of memory with a length of num_bytes bytes

Note: Returns a pointer to the allocated memory if the assignment succeeds, or null if the null pointer is returned.

When memory is no longer in use, you should use the free () function to release the memory block.

The syntax for malloc is: pointer name = (data type *) malloc (length), (data type *) represents a pointer.

Description: malloc allocates the memory space for the specified size byte to the system request. The return type is the void* type. void* indicates an indeterminate type

The pointer. C,c++ stipulates that the void* type can be cast to any other type of pointer.

The working mechanism of the malloc () function

The substance of the malloc function now, it has a so-called idle list that connects the available chunks of memory to a long listing. Call malloc

function, it looks for a block of memory along the join table that is large enough to satisfy the user's request. Then, divide the memory block in two (a large

Small is equal to the size of the user request, and the other size is the remaining byte. Next, the memory assigned to the user is passed to the user, and

Return the remaining piece (if any) to the connection table. When the free function is invoked, it connects the memory blocks freed by the user to the idle chain. To

Finally, the free chain will be cut into a lot of small memory fragments, if the user requests a large memory fragment, then the idle chain may not be able to

To meet the user requirements of the fragment. As a result, the MALLOC function requests a delay and starts rummaging through the free chain to check each memory fragment

To organize and merge the adjacent small free blocks into larger chunks of memory.

The difference between new and

As you can see from the function declaration. malloc and new are at least two different: new returns a pointer of the specified type and can automatically calculate the desired

To size. Like what:

int *p;
p = new int; The return type is the int* type (integer pointer) and the allocation size is sizeof (int);

Or:
Int* Parr;
Parr = new int [100]; The return type is the int* type (integer pointer), and the allocation size is sizeof (int) * 100;

malloc, however, must be calculated by us for the number of bytes, and will be forcibly converted to the actual type of pointer after the return.
int* p;
p = (int *) malloc (sizeof (int));

First, the malloc function returns the void * type if you write: p = malloc (sizeof (int)); The program cannot be compiled,

Error: "Cannot assign void* to int * type variable". So you must pass the cast by (int *).

Second, the function's argument is sizeof (int), which indicates the size required for an integer data. If you write:
int* p = (int *) malloc (1);

The code can also be compiled, but in fact allocates only 1 bytes of memory space, and when you deposit an integer into it, there will be 3 bytes without

Home can return, and directly "live in the neighbor's house"! The result is that the contents of the original data in the back of the memory are all emptied.

3. GlobalAlloc

VC in about Globalalloc,globallock,globalunlock

The GlobalAlloc function is called to allocate a chunk of memory that returns the allocated memory handle.

Call the GlobalLock function to lock a block of memory that takes a memory handle as a parameter and then returns a pointer to the locked block of memory. You can use this pointer to read and write memory.

Call the GlobalUnlock function to unlock previously locked memory, which invalidates the pointer to the memory block.

Call the GlobalFree function to free the memory block. You must pass the function a memory handle.

GlobalAlloc

Description

Allocating a global memory block

return value

Long, which returns the global memory handle. Zero indicates failure. Will set GetLastError

Parameter table

Parameter type and description

Wflags Long, a constant flag that defines the allocated memory type, as follows:
Gmem_fixed allocate a block of fixed memory
Gmem_moveable allocate a removable memory block
Gmem_discardable allocate a disposable memory block
Gmem_nocompact Heap does not accumulate during this function call
No memory blocks are discarded during gmem_nodiscard function calls
Gmem_zeroinit the newly allocated memory blocks are all initialized to 0
Dwbytes Long, number of characters to assign

GlobalLock

Function Description: Locks a global Memory object, returns a pointer to the first byte of the object

Function Prototypes:

LPVOID GlobalLock (Hglobal hmem)

Parameters:

Hmem: The handle of the global memory object. This handle is obtained by GlobalAlloc or GlobalRealloc.

return value:

The call succeeded, returning a pointer to the first byte of the object

Call failed, return NULL, can use GetLastError to get error message

Attention:

After you have called GlobalLock to lock a block of memory, be sure to call GlobalUnlock to unlock

GlobalUnlock

Function Description: Unlocking a locked global memory object

Function prototype: BOOL GlobalUnlock (Hglobal hmem);

Parameters: Hmem: Handle to Global Memory object

return value:

Non-0 value, the specified memory object is still in the locked state 0, function execution error, you can use GetLastError to get the error message, if returned no_error, it means that the memory object has been unlocked

Note: This function is actually to reduce the lock counter of the memory object by one, and if the counter is not 0, it means to execute too many GlobalLock

function to lock the memory object, and a corresponding number of GlobalUnlock functions is required to unlock it. If you return an error through the GetLastError function

If the code is error_not_locked, it means it is unlocked or unlocked.

Example:

Malloc memory
hmem = GlobalAlloc (gmem_moveable | Gmem_ddeshare, nsize);
Lock memory
Pmem = (BYTE *) GlobalLock (HMEM);
..................
Unlock memory
GlobalUnlock (HMEM);
GlobalFree (HMEM);

Three summary

Flexible freedom is a major feature of C/s + + language, and this has also been a problem for C + + programmers. When the program becomes more and more complex, memory management will become more complex, a little careless will appear memory problems. Memory leaks are one of the most common memory problems. Memory leaks if not very serious, in a short period of time will not have much impact on the program, which also makes the memory leak problem has a strong concealment, not easy to be found. However no tube

How small the leak is, when the program is running for a long time, its destructive power is amazing, from performance down to memory exhaustion, even affect the normal operation of other programs. Another common feature of the memory problem is that the memory problem itself does not have a very obvious phenomenon, when there is abnormal phenomenon has changed, its site has not occurred when the problem of the scene, which gives debugging memory problems brought great difficulty.

Download the Windows Debug tool, http://www.microsoft.com/whdc/devtools/debugging/default.mspx

After installation, use the Gflags.exe tool in the pageheap to open the

Gflags-p/enable Maind.exe/full

Reuse vs run with debugging, and quickly find the error location, because a typo in a static function causes

This tool is especially useful when writing a stable server program.

Dynamic distribution and example of the second fractional group

One, the general method of dynamically allocating two-dimensional arrays is this: Suppose that the data type that the array is stored in is int

int **p=null; 
P=new Int*[nwidth];
  if (!p) {return
    NULL;
  }
  for (int j=0;j<nwidth;j++) {
    p[j]=new int[nheight];
    if (!p[j]) {return
      NULL;
    }
  }

This code is easy to understand, the first allocation of the 1th dimension, in the circular allocation of the 2nd dimension. Assuming that the two-dimensional array is 3x2, each sentence after the completion of the memory situation as shown in the diagram (square represents memory, XX represents random number.) The following is the memory address. Of course, this address is a sign that the facts will not be assigned there. ):

3 Memory units allocated after the first sentence

After circular allocation, note that the following 3 segments of memory are not contiguous. The following table P[n][m] Action array is OK, if the whole block of memory operation will be problematic.

The original intention is to put the following 3 pieces of 6 memory units clear 0, but backfired, the beginning of the 6 memory units from the P 0, p[] can not be used. P only has 3 allocated memory units, but it operates 6, and the other 3 are uncharted regions. Clear the 3 unknown areas behind the dotted line, which is dangerous and may cause the program to crash.

This allocated memory requires a circular release.

There is an improvement on this approach, as follows:

int **p=null; 
  p=new int *[nwidth];
if (!p) {return
    NULL;
  }
  P[0]=new Int[nwidth*nheight];
if (!p[0]) {
  delete[] p;
    return NULL;
  }
  ZeroMemory (p[0],nwidth*nheight*sizeof (int));
  for (int i=1;i<nwidth;i++) {
    p[i]=p[i-1]+nheight
  }

This code solves the problem of discontinuous allocation of space. The memory situation after each sentence is as shown in the figure:

The first sentence is the same as above.

These 6 memory units are allocated at one time, so they are contiguous.

The first address of the data in this two-dimensional array is p[0],p, which is the index first address of the 2nd dimension. So if you want to do a whole memory (buffer buffer) operation on a two-dimensional array, take p[0] as the first address of the object.

To this, the index is associated with the corresponding data address. This two-dimensional array can be manipulated by the following table p[][], and it can manipulate the buffer. Functions that manipulate buffers such as Memcpy,cfile Writehuge and Readhuge are easy to use, eliminating the hassle of 2 cycles.

As for release, there is no need to recycle. Because new 2 times, so just delete2 time on the line:

if (!p) {return
  ;
}
  delete []p[0];
  P[0]=null;
  Delete[] p;
  P=null;

Two examples

<span style= "FONT-SIZE:14PX;" 
>//Malloc2d.cpp:Defines The entry point for the console application. #include "stdafx.h" #include <iostream> #include <stdlib.h> #include <string.h> using Namespac 
 
e std; 
  The first method allocates continuous space void **malloc2d (int row,int col,int size) {void **arr; int indexsize=sizeof (void*) *row;//empty out indexsize size space as? 
  void* why not? 
  int totalsize=size*row*col; 
  Arr= (void**) malloc (indexsize+totalsize); if (arr!=null) {unsigned Char *head;//blog is a void *head version, but compilation is not passed, unsigned char* after the compilation passed, but do not understand why the results of the operation is not head= (UN 
    Signed char *) arr+indexsize; 
    memset (arr,0,indexsize+totalsize); 
  for (int i=0;i<row;i++) Arr[i]=head+size*i*col; 
return arr; 
} void Free2d (void **arr) {if (arr!=null) free (arr); 
  }//second method, allocating contiguous space, implementation version of C + +, template <typename t> T **darray_new (int row, int col) {int size=sizeof (t); 
void **arr= (void * * *) malloc (sizeof (void *) * row + size * row * col);  if (arr!= NULL) {unsigned char * head; 
    head= (unsigned char *) arr + sizeof (void *) * row; 
      for (int i=0; i<row; ++i) {arr[i]= head + size * I * COL; 
    for (int j=0; j<col; ++j) New (head + size * (i * col + j)) t;//This is a more interesting sentence, think about why? 
} return (t**) arr; Template <typename t> void Darray_free (T **arr, int row, int col)/Note to one delete, the egg hurts, but for the custom data type, it is necessary {F or (int i=0; i<row; ++i) for (int j=0; j<col; ++j) arr[i][j].~t ();//What the hell is this?! Template destructor? Because you used new? 
  So with the destructor's delete? 
if (arr!= NULL) Free ((void * *) arr); 
  } int _tmain (int argc, _tchar* argv[]) {//one-dimensional array dynamically allocated//int N; 
  cin>>n; 
  An int *p=new int[n];//dynamic allocation method of one-dimensional array//int *p= (int*) malloc (n*sizeof (int));//one-dimensional array dynamic allocation method two//for (int i=0;i<n;i++) 
  cin>>p[i]; 
  cout<<endl; 
 
  for (int i=0;i<n;i++)//cout<<p[i]<< ""; Two-dimensional variable-length array dynamic allocation, I like this method, although the space is not continuous, but also can carry out p[i][j] addressing, why the blog deliberately write aboveThe introduction of the function to achieve has not found too good reason for//int N; 
  cin>>n; 
  int *p[2]; 
  P[0]=new Int[n]; 
  P[1]=new int[n+1]; 
  for (int i=0;i<n;i++)//cin>>p[0][i];   cout<<&p[0]<< "" <<&p[1]<<endl;//p[0],p[1] is a continuous//cout<<&p[0]<< " "<<&p[0][0]<<" "<<&p[0][1]<<endl;//p[0]!=p[0][0], but p[0][0],p[0][1] is a continuous version of the////c, divided 
  With continuous space//int**m= (int**) malloc2d (5,5,sizeof (int)); 
  int i,j; 
  for (i=0;i<5;i++)//void* generic pointers, to be profiled//for (j=0;j<5;j++)//m[i][j]=0; 
  for (i=0;i<5;i++)//{//For (j=0;j<5;j++)//cout<<m[i][j]<< ""; 
  cout<<endl; 
 
 
  }//free2d ((void**) m); 
  int** m=darray_new<int> (5,5)//Notice how the template function is implemented <int>! 
  int i,j; 
  for (i=0;i<5;i++) for (j=0;j<5;j++) m[i][j]=1; 
    for (i=0;i<5;i++) {for (j=0;j<5;j++) cout<<m[i][j]<< ""; cout<<endl;
  } darray_free (m,5,5); 
return 0;  } </span>

Above this article on C + + memory allocation and variable-length array dynamic distribution is a small series to share all the content, hope to give you a reference, but also hope that we support the cloud habitat community.

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.