malloc,指针,throw的总结

本文详细阐述了C++中`throws`和`throw`的区别,通过实例展示了如何在方法中正确地抛出异常。重点讨论了异常抛出的时机、异常处理的流程以及如何避免潜在的调试陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1)关于 malloc函数 的笔记: 
1、当一个程序另外需要一些内存时,它就调用malloc()函数,malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针。这块内存此时并没有以任何方式进行初始化。(是指针指向的内存没有初始化,不是指针没有初始化。) 
2、当一块以前分配的内存不再使用时,调用free函数把它归还给内存池以供以后之需。 
3、malloc所分配的是一块连续的内存。 
4、对每个从malloc返回的指针都进行检查,确保它并非NULL是非常重要的!!!!! 

5、malloc与calloc之间的主要区别是后者在返回指向内存的指针之前把内存初始化为0(对于指针是NULL)。


2)关于指针的笔记: 
1、所有的基本数据类型最终都被解释成一串二进制码,也就是说,当给定一串二进制码时,它可能被映射成int,也可能被映射成char,float,double等数据类型。 
2、声明一个指针后,操作系统并不会为它分配空间。所以在访问指针前必须初始化。 
3、如果知道指针被初始化为什么地址,就把它初始化为该地址,否则就把它初始化为NULL。风格良好的程序会在指针解引用之前对它进行检查,这种初始化策略可以减少大量的调试时间。 
4、左值表示存储在计算机内存的对象,左值相当于地址值。右值:当一个符号或者常量放在操作符右边的时候,计算机就读取他们的“右值”,也就是其代表的真实值,右值相当于数据值。 
5、&a只能做右值。 
6、定义char *string;则表达式 *string++ 执行过程:(1)++操作符产生string的一份拷贝(2)然后++操作符增加string的值(3)最后在string拷贝上执行间接访问操作。 
这个表达式经常用在循环中 !note:++操作符优先级高于* 
7、指针数组以一个NULL指针结束。 
**8、**p为一个指针,p+1 (指针与整数加法)的结果与类型无关。若p为int,则p增加一个int即四个字节,若p为char,则p增加一个char即一个字节


3)throw:

如果出现了异常情况,我们可以把该异常抛出,这个时候的抛出的应该是异常的对象。
  
  throws和throw的区别(面试题)
    throws
        用在方法声明后面,跟的是异常类名
        可以跟多个异常类名,用逗号隔开
        表示抛出异常,由该方法的调用者来处理
        throws表示出现异常的一种可能性,并不一定会发生这些异常
    throw
        用在方法体内,跟的是异常对象名
        只能抛出一个异常对象名
        表示抛出异常,由方法体内的语句处理

        throw则是抛出了异常,执行throw则一定抛出了某种异常

源代码:

[java]  view plain copy
  1. public class Throws_Throw {  
  2.     public static void main(String[] args) {  
  3.         // method();//调用此方法没必要try-catch因为抛得是运行时期的异常  
  4.           
  5.         try {  
  6.             method2();//调用此方法必须要try-catch因为抛得的编译器  
  7.         } catch (Exception e) {  
  8.             e.printStackTrace();  
  9.         }  
  10.     }  
  11.   
  12.     public static void method() {  
  13.         int a = 10;  
  14.         int b = 0;  
  15.         if (b == 0) {  
  16.             throw new ArithmeticException();  
  17.         } else {  
  18.             System.out.println(a / b);  
  19.         }  
  20.     }  
  21.   
  22.     public static void method2() throws Exception {  
  23.         int a = 10;  
  24.         int b = 0;  
  25.         if (b == 0) {  
  26.             throw new Exception();  
  27.         } else {  
  28.             System.out.println(a / b);  
  29.         }  
  30.     }  
  31. }  

### C++ 中 `new` 和 `malloc` 的内存分配区别及使用场景 #### 1. **类型安全性** `malloc` 返回的是 `void*` 类型,这意味着它并不知道所分配的内存的具体用途,在实际使用时需要进行显式的类型转换。而在 C++ 中,这种做法容易引发潜在的类型错误[^3]。 相比之下,`new` 运算符具有更高的类型安全性,因为它是基于对象类型的,能够自动推导并返回相应的指针类型,无需额外的类型转换[^5]。 ```cpp int* ptrMalloc = (int*)malloc(sizeof(int)); // 需要显式类型转换 int* ptrNew = new int; // 自动推导类型,无需转换 ``` #### 2. **构造与析构函数的支持** 当涉及到类对象的动态分配时,`malloc` 只负责分配原始的未初始化的内存块,并不会调用任何构造函数或析构函数。这使得 `malloc` 对象的状态可能不符合预期,尤其是在复杂的数据结构中[^4]。 相反,`new` 不仅分配内存,还会立即调用对应的构造函数来初始化对象。同样地,在释放内存时,`delete` 负责先调用析构函数再释放资源,从而确保对象生命周期内的正确行为[^2]。 ```cpp class MyClass { public: MyClass() { std::cout << "Constructor called\n"; } ~MyClass() { std::cout << "Destructor called\n"; } }; // 使用 malloc 分配内存,但不调用构造函数 MyClass* objMalloc = (MyClass*)malloc(sizeof(MyClass)); free(objMalloc); // 不会调用析构函数 // 使用 new 分配内存,同时调用构造函数 MyClass* objNew = new MyClass(); // 构造函数被调用 delete objNew; // 析构函数被调用后再释放内存 ``` #### 3. **错误处理机制** 如果 `malloc` 或者 `calloc` 在尝试分配内存时失败,则会简单地返回一个空指针 (`nullptr`)。开发者需要自行检查该返回值以判断是否成功分配了足够的内存[^1]。 然而,`new` 默认情况下会在无法获取所需内存时抛出异常 `std::bad_alloc`。这种方式更符合现代 C++ 编程风格,允许程序员利用异常处理机制优雅地应对错误情况。当然也可以通过指定 `nothrow` 参数让其像 `malloc` 一样返回零值而非抛出异常[^5]。 ```cpp try { int* largeArray = new(std::nothrow) int[1000000]; // 尝试分配大数组 if (!largeArray) throw std::runtime_error("Memory allocation failed"); } catch(const std::exception& e){ std::cerr << e.what(); } ``` #### 4. **多态性和虚析构函数支持** 由于 `delete` 会考虑基类中的虚拟表(vtable),所以即使是从派生类实例化而来并通过基类指针指向的对象也能得到恰当销毁——即调用了正确的虚析构函数版本[^5]。这是面向对象设计的重要特性之一,而单纯依靠 `free()` 则不可能实现这一点。 ```cpp class Base {}; class Derived : public Base {}; Base *basePtr = new Derived; delete basePtr; // 正确删除派生类对象,前提是定义了虚析构函数 // free(basePtr); // 错误:不能保证正确清理资源 ``` #### 5. **适用范围和推荐实践** 尽管两者都能完成基本的堆上存储需求,但由于上述原因,在纯 C++ 环境下强烈建议优先选用 `new/delete` 组合来进行动态内存管理,特别是涉及复杂的自定义数据类型时更是如此[^3]。不过需要注意的是,有时候为了兼容旧版 API 或与其他低级语言交互等原因仍需偶尔借助于 `malloc/free` 工具集;另外在追求极致性能优化场合也可能偏好后者因省去了额外开销。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值