Can new data be used free?

From: http://blog.csdn.net/stpeace/article/details/39087571

My title is an interview question I saw today. After seeing it, I didn't rush to answer it, but thought about it.

Using my own intuition, I guessed the answer of "no", although it is correct, but I don't know why. then

I checked the information:

No, new corresponds to delete and cannot be worn.
malloc/free, new/delete must be paired.
malloc and free are standard library functions of C++ and C language , and new and delete are operators of C++. Both of them can be used to allocate dynamic memory and free memory. For objects of non-internal data types, malloc/free alone cannot meet the requirements of dynamic objects. The object should automatically execute the function when it is created, and the destructor should be automatically executed before the object is destroyed. Since malloc/free is a library function rather than an operator, it is not within the control of the compiler, and the task of executing the constructor and destructor cannot be imposed on malloc/free. Therefore, the C++ language needs an operator new that can complete the work of dynamic memory allocation and initialization, and an operator delete that can complete the work of cleaning up and freeing memory. Note that new/delete are not library functions.


The essence of new and delete is a function, malloc and free are just a call statement in these two functions , so when you use new to apply for memory, but use free to release it, it is equivalent to using the entire function to apply for memory and maintain a logical function The memory is easy to use, but only one free statement is used to release the memory, which makes this logic error, because this is a logic error rather than a syntax error, so the compiler will not recognize it (the cow B may warn). There is a serious problem with your program instructions, and you have to segfault or spit the core. It happens that this problem does not affect the operating system, and it does not mean that this is a good program.

In-depth analysis of the difference between new and malloc


1. malloc() function
1.1 The full name of malloc is memory allocation, which is called dynamic memory allocation in Chinese.
Prototype: extern void *malloc(unsigned int num_bytes); 
Description: Allocate a memory block with a length of num_bytes bytes. If the allocation is successful, it returns a pointer to the allocated memory, and if the allocation fails, it returns a null pointer NULL. When the memory is no longer used, the free() function should be used to free the memory block.

1.2 void *malloc(int size); 
Description: malloc applies to the system to allocate memory space of specified size bytes, and the return type is void*. void* represents a pointer of undetermined type. C, C++ stipulates that void* type can be cast to any other type of pointer.   
Remarks: void* represents a pointer of undetermined type. More specifically, it means that when applying for memory space, it is not known what type of data the user uses this space to store (such as char or int or...)

1.3 free
void free(void *FirstByte): This function returns the space allocated by malloc to the program or the operating system , that is, releases the memory and makes it free again.

1.4 Notes
1) After applying for memory space, you must check whether the allocation is successful.

2) When you don't need to use the requested memory, remember to release it; after release, you should point the pointer to this memory to NULL to prevent the program from accidentally using it later.

3)这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。

4)虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。

1.5  malloc()到底从哪里得到了内存空间?
答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。

2. new运算符

2.1 C++中,用new和delete动态创建和释放数组或单个对象。
动态创建对象时,只需指定其数据类型,而不必为该对象命名,new表达式返回指向该新创建对象的指针,我们可以通过指针来访问此对象。
int *pi=new int;
这个new表达式在堆区中分配创建了一个整型对象,并返回此对象的地址,并用该地址初始化指针pi 。

2.2 动态创建对象的初始化
动态创建的对象可以用初始化变量的方式初始化。
int *pi=new int(100); //指针pi所指向的对象初始化为100
string *ps=new string(10,'9');//*ps 为“9999999999”

如果不提供显示初始化,对于类类型,用该类的默认构造函数初始化;而内置类型的对象则无初始化。
也可以对动态创建的对象做值初始化:
int *pi=new int( );//初始化为0
int *pi=new int;//pi 指向一个没有初始化的int
string *ps=new string( );//初始化为空字符串 (对于提供了默认构造函数的类类型,没有必要对其对象进行值初始化)

2.3 撤销动态创建的对象
delete表达式释放指针指向的地址空间。
delete pi ;// 释放单个对象
delete [ ]pi;//释放数组
如果指针指向的不是new分配的内存地址,则使用delete是不合法的。

2.4 在delete之后,重设指针的值
delete p; //执行完该语句后,p变成了不确定的指针,在很多机器上,尽管p值没有明确定义,但仍然存放了它之前所指对象的地址,然后p所指向的内存已经被释放了,所以p不再有效。此时,该指针变成了悬垂指针(悬垂指针指向曾经存放对象的内存,但该对象已经不存在了)。悬垂指针往往导致程序错误,而且很难检测出来。
一旦删除了指针所指的对象,立即将指针置为0,这样就非常清楚的指明指针不再指向任何对象。(零值指针:int *ip=0;)

2.5 区分零值指针和NULL指针
零值指针,是值是0的指针,可以是任何一种指针类型,可以是通用变体类型void*也可以是char*,int*等等。
空指针,其实空指针只是一种编程概念,就如一个容器可能有空和非空两种基本状态,而在非空时可能里面存储了一个数值是0,因此空指针是人为认为的指针不提供任何地址讯息。

2.6 new分配失败时,返回什么?
1993年前,c++一直要求在内存分配失败时operator   new要返回0,现在则是要求operator   new抛出std::bad_alloc异常。很多c++程序是在编译器开始支持新规范前写的。c++标准委员会不想放弃那些已有的遵循返回0规范的代码,所以他们提供了另外形式的operator   new(以及operator   new[])以继续提供返回0功能。这些形式被称为“无抛出”,因为他们没用过一个throw,而是在使用new的入口点采用了nothrow对象: 
class   widget   {   ...   };

widget   *pw1   =   new   widget;//   分配失败抛出std::bad_alloc  

if   (pw1   ==   0)   ... //   这个检查一定失败

widget   *pw2   =   new   (nothrow)   widget;   //   若分配失败返回0

if   (pw2   ==   0)   ... //   这个检查可能会成功

3. malloc和new的区别

3.1 new 返回指定类型的指针,并且可以自动计算所需要大小。
比如:   
1)
 int *p;   
p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);   
或:   
int* parr;   
parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;   

2) 而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。   
int* p;   
p = (int *) malloc (sizeof(int)*128);//分配128个(可根据实际需要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中  
double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将首地址存储到指针变量pd中

3.2 malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。

4.有了malloc/free为什么还要new/delete?
1)
 malloc与free是C++/c语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。

2)  For objects of non-internal data types, maloc/free alone cannot meet the requirements of dynamic objects. Objects automatically execute constructors when they are created, and destructors are automatically executed before objects die. Since malloc/free is a library function rather than an operator, it is not within the control of the compiler, and the task of executing the constructor and destructor cannot be imposed on malloc/free.

Therefore, the C++ language needs an operator new that can complete the work of dynamic memory allocation and initialization, and an operator delete that can complete the work of cleaning and freeing memory. Note that new/delete are not library functions.

We should not try to use malloc/free to complete the memory management of dynamic objects, we should use new/delete. Since the "object" of the internal data type has no construction and destruction process, malloc/free and new/delete are equivalent for them.

3)  Since the functions of new/delete completely cover malloc/free, why doesn't C++ eliminate malloc/free? This is because C++ programs often call C functions, and C programs can only manage dynamic memory with malloc/free.

If the "dynamic object created by new" is freed with free, then the object may cause a program error because the object cannot execute the destructor. If you use delete to release the "dynamic memory requested by malloc", the result will also cause a program error, but the readability of the program is very poor. So new/delete must be used in pairs, as does malloc/free.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325475644&siteId=291194637