malloc () and calloc ()

malloc () and calloc ()

Process a request for dynamic memory is not considered urgent. For example, when a process executable file is loaded, the process is not necessarily immediate access to all of the code. Similarly, when the process calls malloc () request dynamic memory, does not mean that the process will soon have access to all the memory available. Therefore, in general, always try to postpone the kernel to user mode processes dynamically allocated memory.
    The kernel succeeds in deferring the allocation of dynamic memory to processes by using a new kind of resource When a User Mode process asks for dynamic memory, it does not get additional page frames;. Instead, it gets the right to use a new range of linear addresses, which become part of its address space. This interval is called a "memory region."

    kernel uses a resource for the successful implementation of dynamic memory allocation to postpone the process. When a user mode process request dynamic memory, and did not get the requested page frame, but only to obtain the right to use a new linear address area, and this linear address range to become part of the process address space. This range is called the linear region (Memory Region).
    At The Page Fault Exception Handler in deferring at The Allocation of page frames to Processes. Missing page exception handler eventually get the current page frames needed for the process. Excerpt from "in-depth understanding of linux kernel (second Version) "P269 - process address space of a chapter

    brk () system call is the most common, by which a user process to the kernel space applications (memory region and perhaps page frames). By malloc () is a Class C language library functions used indirectly brk (). If malloc () thought of as retail, brk () is wholesale. Library function malloc () is a user process to maintain a small warehouse, when the process requires more memory space is to be a small warehouse, on the adoption of brk () to the kernel when small wholesale warehouse inventory shortage. alloc () is used Indirect how brk () is? "Scenario analysis (on)" P160




malloc ()
--------------------------------------- ----
    the malloc () function is used to allocate memory: the total of the number of bytes passed as a parameter to the function, the return value is a pointer to memory newly assigned, and if the memory allocation is not good, then the value returned is NULL .
malloc () the use of technology:
    some_type * pointer;
    pointer = malloc (sizeof * COUNT (* pointer));

Note:
(1) This method ensures malloc () will allocate the correct amount of memory, regardless of life pointer. If the type of pointer later changed, sizeof operator automatically ensure that the number of bytes to be allocated is still correct.
(2) malloc () returns the memory is "no" initialization. This memory may contain any random junk, you can use right away, or at least valid data to initialize this memory with zeroes. 0 Initialization use, may be
void * memset (void * s, int c, size_t n);
(3) malloc () eventually acquired by missing page abnormal physical memory of the original data, in most cases is 0 (but is not guaranteed 0)



calloc ()
------------ -------------
    calloc () malloc function is a simple wrapper. Its main advantage is that the dynamically allocated memory is cleared.
    void * calloc (size_t nmemb, size_t size);
    with experienced programmers prefer to use calloc (), because the content of newly allocated memory so there would be no problem, call the calloc () will certainly be cleared, and to avoid calling memset ().



malloc () practice
----------------------------------------- ------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char *a;
    a = (char *)malloc(10 * sizeof(*a)); //(1)
    memset(a, 'a', 10);          //(2)
    printf("a = %s ", a);
    free(a);                    //(3)
    a = NULL;                  //(5)

    B * char;
    B = (char *) the malloc (10 * the sizeof (* B)); // (. 4)
    Memset (B, 'B', 10);
    the printf ( "% S = A", A);
    the printf ( "% S = B", B);
    Free (B);
}

Note:
------------------------------- ----------
(1)
user address space (virtual memory)
          | |
          | -------- |            
          | |           
          | | 10bytes
          | |           
A -------> | | 0x804a008  
          | -------- |           
          | |
a = malloc (); after performing


(2)
true physical memory on this page by the lack of an exception to get

| ------------ | - ----------- | -------------- |
| 0000100000 | 0001001010 | 000000001000 |
|------------|------------|--------------|
   |                 |                  |
   | -
|---------|    |   |---------|    |    |---------|
   |
-
|         |    |   |         |    |    |         |
   |
-
|         |    |   |         |    |    |---------|
   |
-
|         |    |   |         |    |    |    a    |
   |
-
|         |    |   |         |    |    |   ...   |10bytes
   | - |         |    |   |         |    |    |   ...   |
   +->|         |--+ +-->|         |--+ |    |    a    |
      |         |
- | | | -
| + ---> | - ------- |
      | |
- | | | -
| | |
      | --------- |
- + ----> | --------- | -
+ -----> | --------- |
         page directory table page table data stored valid physical page
                        of physical memory

memset (a, 'a', 10); post


(3)
    performs Free (a) after a period of user space remains directed at 0x804a008, but the space is no longer belongs to a pointer management, the corresponding physical memory is also cleared up and recovered. If the pointer is released immediately after a visit to which it refers the use of a space again, missing page exception process space allocation for the new physical memory again (before the piece of physical space may still be released, but has been cleared up).

    If a new dynamic memory requests b = malloc (), a pointer to the released process space may be reassigned. Pointer a then still can access (read or write) the process space corresponding to the physical space (the physical space is access to the new pointer exception for the new pointer allocated by the missing pages, probably as a pointer p allocated physical memory) (no error), but such operations are illegal because the space could have been the new owner (the new guidelines) under management.

(4)
User address space
          | |
          | -------- |
          | |
          | | 10bytes
          | |
B -------> | | 0x804a008
(A) | -------- |
          | |
B = malloc (); after performing
    this case both a and b point to the same process space (space corresponding to the process is the same physical space), the operation of a or b will be the same in both operating space (physical space), which is very dangerous because this is really the owner of the space is b, but also has the ability to modify a space b referred to in (Wow! the former owner had to sneak into the house, the new owner of the property may be dangerous)

( 5)
    so that upon release process space pointer, once the pointer should be set to a null pointer. The pointer will be no chance to visit before the process space!

malloc()和calloc()都是用于分配内存的函数。
函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别。

malloc()函数有一个参数,即要分配的内存空间的大小:
void*malloc(size_tsize);

calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小。
void*calloc(size_tnumElements,size_tsizeOfElement);

如果调用成功,函数malloc()和函数calloc()都将返回所分配的内存空间的首地址。

函数malloc()和函数calloc() 的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之, 如果这部分内存曾经被分配过,则其中可能遗留有各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常进行,但经过一段时间(内存空间还已经被重新分配)可能会出现问题。

函数calloc() 会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那麽这些元素将保证会被初始化为0;如果你是为指 针类型的元素分配内存,那麽这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

memset

  功 能: 将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值,
  块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作
  用 法: void * memset (void *s, char ch, unsigned n);
  程序例:
  #include <string.h>
  #include <stdio.h>
  #include <mem.h>
  int main(void)
  {
  char buffer[] = "Hello world/n";
  printf("Buffer before memset : %s/n", buffer);
   memset (buffer, '*', strlen(buffer) );
  printf("Buffer after memset : %s/n", buffer);
  return 0;
  }
  输出结果:
  Buffer before memset : Hello world
  Buffer after memset : ***********
  编译平台:
  Microsoft Visual C++ 6.0
  也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。例如下面这样:
  int array[5] = {1,4,3,5,2};
  for(int i = 0; i < 5; i++)
  cout<<array <<" ";
  cout<<endl;
   memset (array,0,5*sizeof(int));
  for(int k = 0; k < 5; k++)
  cout<<array [k] <<" ";
  cout<<endl;
  输出的结果就是:1 4 3 5 2
  0 0 0 0 0
  后面的表大小的参数是以字节为单位,所以,对于int或其他的就并不是都乘默认的1(字符型)了。而且不同的机器上int的大小也可能不同,所以最好用sizeof()。
   要注意的是,memset 是对字节进行操作,所以上述程序如果改为
  int array[5] = {1,4,3,5,2};
  for(int i = 0; i < 5; i++)
  cout<<array <<" ";
  cout<<endl;
   memset (array,1,5*sizeof(int));// 注意 这里与上面的程序不同
  for(int k = 0; k < 5; k++)
  cout<<array [k] <<" ";
  cout<<endl;
  输出的结果就是:1 4 3 5 2
  16843009 16843009 16843009 16843009 16843009
   为什么呢?
   因为memset 是以字节为单位 就是对array指向的内存的5个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是1000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。
  所以用 memset 对非字符型数组赋初值是不可取的!
  楼上说的很对,只是程序执行结果是0 0 0 0;程序不同的地方不在那里。程序如下:
  int array[5] = {1,4,3,5,2};
  for(int i = 0; i < 5; i++)
  cout<<array<<" ";
  cout<<endl;
   memset (array,1,5*sizeof(int)); //这里才是不同的地方
  for(int k = 0; k < 5; k++) //不同不在这里,k=1只是少循环了一次而已
  cout<<array[k]<<" ";
  cout<<endl;
  例如有一个结构体Some x,可以这样清零:
   memset ( &x, 0, sizeof(Some) );
  如果是一个结构体的数组Some x[10],可以这样:
  menset( x, 0, sizeof(Some)*10 );

memset 函数详细说明

  1。void * memset (void *s,int c,size_t n)
  总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。
  2。例子
  main(){
  char *s="Golden Global View";
  clrscr();
   memset (s,'G',6);//貌似这里有点问题//
  printf("%s",s);
  getchar();
  return 0;
  } 
  【这个问题相当大,程序根本就运行不下去了,你这里的S志向的是一段只读的内存,而你 memset 又试图修改它,所以运行时要出错,修改办法char *s修改为char s[]】
修改后如下:

#include <stdio.h>
#include <string.h>

int main()
{
 char s[]="Golden Global View";
 memset(s,'G',strlen(s));//貌似这里有点问题//
 printf("%s",s);
 return 0;
}


 
  3。 memset () 函数常用于内存空间初始化。如:
  char str[100];
   memset (str,0,100);
  4。 memset ()的深刻内涵:用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ memset (a, '/0', sizeof(a));
  memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。
  strcpy就只能拷贝字符串了,它遇到'/0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘/0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。
  5.补充:某人的一点心得
   memset 可以方便的清空一个结构类型的变量或数组。
  如:
  struct sample_struct
  {
  char csName[16];
  int iSeq;
  int iType;
  };
  对于变量
  struct sample_strcut stTest;
  一般情况下,清空stTest的方法:
  stTest.csName[0]='/0';
  stTest.iSeq=0;
  stTest.iType=0;
  用 memset 就非常方便:
   memset (&stTest,0,sizeof(struct sample_struct));
  如果是数组:
  struct sample_struct TEST[10];
  则
   memset (TEST,0,sizeof(struct sample_struct)*10);
  6。strcpy
  原型:extern char *strcpy(char *dest,char *src);
  用法:#i nclude
  功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
  Description: memory pointed to src and dest dest region may not overlap and must have sufficient space to accommodate the character string src.
  Returns a pointer pointing to dest.
  memcpy
  原型:extern void *memcpy(void *dest, void *src, unsigned int count);
  Usage: #i nclude
  Function: copy count bytes to the memory area indicated by the src dest referred memory area.
  Description: src and dest referred memory area can not be overlapped, the function returns a pointer to a pointer dest.
   memset
  原型:extern void * memset (void *buffer, int c, int count);
  Usage: #i nclude
  Function: the first count bytes of buffer memory region provided within the meaning of the character c.

  Description: Returns a pointer to the buffer pointer.

Reproduced in: https: //my.oschina.net/dake/blog/196646

Guess you like

Origin blog.csdn.net/weixin_33675507/article/details/91508250