1. 完成 160. 相交链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// 如果链表 A 的头节点为空或者链表 B 的头节点为空,直接返回 nullptr,表示没有交点
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode* a = headA;
ListNode* b = headB;
// 循环直到找到交点或者两个指针都为 nullptr
while (a!= b) {
// 如果指针 a 到达链表 A 的末尾,则将其指向链表 B 的头节点,继续遍历
a = a == nullptr? headB : a->next;
// 如果指针 b 到达链表 B 的末尾,则将其指向链表 A 的头节点,继续遍历
b = b == nullptr? headA : b->next;
}
// 返回找到的交点,如果没有交点则返回 nullptr
return a;
}
};
2. 八股部分
1)解释一下 new 和 delete 运算符在 C++ 中的作用。
一、new
运算符的作用
-
动态内存分配:
new
用于在程序运行时从堆上分配内存空间。与在编译时确定内存大小的静态内存分配不同,动态内存分配允许根据程序的实际需求在运行时决定所需的内存大小。- 例如:
int* ptr = new int;
这里为一个整数分配了内存空间,并将指向该内存的指针存储在ptr
中。 - 也可以为数组分配内存:
int* arr = new int[10];
为包含 10 个整数的数组分配内存。
-
调用构造函数:
- 对于类类型,
new
不仅分配内存,还会调用适当的构造函数来初始化对象。 - 例如:
MyClass* obj = new MyClass(parameters);
这里在分配内存后调用了MyClass
的构造函数,并传入相应的参数来初始化新创建的对象。
- 对于类类型,
二、delete
运算符的作用
-
释放动态分配的内存:
delete
用于释放由new
分配的内存空间,以防止内存泄漏。- 例如:
delete ptr;
如果ptr
是通过new int
分配的指针,这条语句将释放该整数所占用的内存。 - 对于数组:
delete[] arr;
如果arr
是通过new int[size]
分配的数组指针,必须使用delete[]
来释放整个数组的内存。
-
调用析构函数:
- 对于类类型,
delete
在释放内存之前会调用对象的析构函数,以执行必要的清理操作。 - 例如:当释放一个指向类对象的指针时,
delete obj;
会先调用obj
所指向对象的析构函数,然后再释放内存。
- 对于类类型,
2)什么是内存泄漏?如何避免内存泄漏?
什么是内存泄漏?
内存泄漏 memory leak ,是指程序申请内存后,无法释放已申请的内存空间,一次内存泄漏危害可以忽略,但内存堆积后果很严重,无论多少内存,迟早会被占光。
内存泄漏是指你向系统申请分配内存进行(new),可是使用完以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问,(也行是你把它的地址弄丢了),而系统也不能再次将它分配给需要的程序。(了解一下然后查找解决内存泄漏 vs 提供了工具)
void fun(){ int *p=new int(3);//没有delete }
如何避免内存泄漏?
-
在函数申请一块内存,函数结束指针没有释放该堆区内存
-
在父类指针或引用时,没有将父类的析构函数设置为虚析构
-
指针需要重新赋值
-
智能指针的循环引用问题(weal_ptr 解决循环引用可以给面试官画图讲解)
#include <iostream>
#include <memory>
class Child; // 前向声明
class Parent {
public:
std::shared_ptr<Child> childPtr; // Parent 拥有 Child 的共享指针
~Parent() {
std::cout << "Parent destroyed" << std::endl;
}
};
class Child {
public:
std::weak_ptr<Parent> parentPtr; // Child 拥有 Parent 的弱指针
~Child() {
std::cout << "Child destroyed" << std::endl;
}
};
int main() {
{
// 创建 Parent 对象
auto parent = std::make_shared<Parent>();
// 创建 Child 对象
auto child = std::make_shared<Child>();
// 设置关系
parent->childPtr = child; // Parent 持有 Child 的共享指针
child->parentPtr = parent; // Child 持有 Parent 的弱指针
// 打印出 Parent 和 Child 的引用计数
std::cout << "Parent reference count: " << parent.use_count() << std::endl; // 输出 1
std::cout << "Child reference count: " << child.use_count() << std::endl; // 输出 1
} // parent 和 child 都超出作用域,应该会正确释放
std::cout << "Exited the scope" << std::endl;
return 0;
}
标签:delete,int,每日,nullptr,计划,内存,new,1031,指针
From: https://blog.csdn.net/asd_hero/article/details/143419349