当前位置: 首页 > article >正文

力扣 对称二叉树-101

对称二叉树-101

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr)return true;
        return cmp(root->left,root->right);
    }
    bool cmp(TreeNode* left1,TreeNode* left2)
    {
        //如果两个树都为空,返回true,表示对称。
        if(!left1&&!left2)return true;
        //如果上一个if没有执行没有返回true,并且这行if判断成立的话,就是一个树为空一个树不为空,返回false,表示不对称。
        if(!left1||!left2)return false;
        bool LandR = cmp(left1->left,left2->right);//递归左子树的左子节点与右子树的右子节点。
        bool RandL = cmp(left1->right,left2->left);//递归左子树的右子节点与右子树的左子节点。
        //如果每个节点对应的值相同,并且树的结构是对称的就返回true,否则返回false
        return left1->val==left2->val&&LandR&&RandL;
    }
};

每日问题

请解释new和malloc的区别,并分别解释他们的用法

new 和 malloc 都是用于动态内存分配的操作符,但它们在 C++ 和 C 语言中有所不同。以下是它们之间的区别以及各自的用法。

1. malloc(C语言)

malloc 是 C 语言中的函数,用于从堆(heap)中动态分配一块指定大小的内存。它的原型定义在 头文件中。

语法:
void* malloc(size_t size);

size 是要分配的内存的字节数。

返回值是一个 void* 指针,指向分配的内存区域。如果分配失败,返回 NULL。

用法:
#include <stdlib.h>

int* ptr = (int*)malloc(sizeof(int) * 10);  // 分配10个int类型大小的内存
if (ptr == NULL) {
    // 内存分配失败,处理错误
}
特点:

        malloc 只分配内存,不初始化内存。分配的内存中的值是未定义的。

        需要手动进行类型转换(如 int*)。

        分配失败时返回 NULL。

2. new(C++语言)

new 是 C++ 中的操作符,功能类似于 malloc,用于动态分配内存。new 会在堆上分配指定大小的内存,并且初始化对象(如果是类类型的话)。

语法:

pointer = new type;                 // 分配一个对象
pointer = new type[size];           // 分配一个数组

new 会返回指向分配内存区域的指针。如果分配失败,会抛出一个 std::bad_alloc 异常,而不是返回 NULL。

new[] 用于分配数组,new 用于分配单个对象。

用法:
#include <iostream>

int* ptr = new int(10);  // 分配一个int类型内存,并初始化为10
int* arr = new int[10];   // 分配10个int类型的数组
特点:

        new 会初始化内存,如果是基础数据类型,则会将其初始化为默认值(例如,int 会初始化为 0)。对于类对象,会调用类的构造函数。

        new 会自动进行类型转换。

        如果内存分配失败,new 会抛出 std::bad_alloc 异常,而不是返回 NULL。

        使用 new[] 分配的数组应该用 delete[] 来释放。

3. malloc 和 new 的区别

内存初始化:

        malloc 不会初始化分配的内存,内存中的内容是未定义的。

        new 会初始化内存,对于基本类型初始化为零,对于类类型会调用构造函数。

返回类型:

        malloc 返回的是 void* 指针,需要手动进行类型转换。

        new 返回的是指向指定类型的指针,自动进行类型转换。

异常处理:

        malloc 如果分配失败,会返回 NULL,需要手动检查。

        new 如果分配失败,会抛出 std::bad_alloc 异常。

适用语言:

        malloc 是 C 语言中的函数,可以在 C 中使用。

        new 是 C++ 中的操作符,推荐在 C++ 中使用。

4. 释放内存

        使用 malloc 分配的内存必须使用 free 来释放:free(ptr);

        使用 new 分配的内存必须使用 delete 来释放(单个对象):delete ptr;

        使用 new[] 分配的数组必须使用 delete[] 来释放:delete[] arr;

示例代码:

使用 malloc(C语言):
#include <stdlib.h>
#include <stdio.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int) * 5);  // 分配一个整数数组
    if (ptr == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }

    // 使用内存
    for (int i = 0; i < 5; i++) {
        ptr[i] = i * 10;
        printf("%d ", ptr[i]);
    }

    // 释放内存
    free(ptr);
    return 0;
}
使用 new(C++语言):
#include <iostream>
using namespace std;

int main() {
    int* ptr = new int(5);  // 分配一个整数并初始化为5
    cout << *ptr << endl;  // 输出5

    // 使用内存
    int* arr = new int[5];  // 分配一个数组
    for (int i = 0; i < 5; i++) {
        arr[i] = i * 10;
        cout << arr[i] << " ";
    }

    // 释放内存
    delete ptr;     // 释放单个对象
    delete[] arr;   // 释放数组
    return 0;
}

总结:

        malloc 是 C 中的动态内存分配函数,返回 void* 类型的指针,不初始化内存。

        new 是 C++ 中的操作符,返回指向指定类型的指针,并且会初始化内存,且支持异常处理。

malloc分配失败会导致什么问题

malloc 分配内存失败会导致一些潜在的问题,最主要的问题是程序没有获取到所需的内存空间。具体来说,malloc 分配内存失败时会返回 NULL,如果没有适当地处理这个错误,可能会导致以下几种情况:

1. 程序崩溃(Segmentation Fault)

如果 malloc 返回 NULL,而程序没有检查这一点,直接使用这个 NULL 指针进行读写操作,将导致程序崩溃,通常表现为 Segmentation Fault 或 Access Violation 错误。这是因为对空指针进行解引用是非法的。

示例:

#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int) * 1000000000);  // 请求分配过大的内存
    if (ptr == NULL) {
        // 忽略分配失败,直接使用指针
        *ptr = 10;  // 访问空指针,导致崩溃
    }
    return 0;
}

在这个示例中,malloc 分配失败时返回 NULL,但如果不检查 NULL,后续访问 *ptr 就会导致崩溃。

2. 未定义行为(Undefined Behavior)

如果 malloc 分配失败时没有检查其返回值并继续使用 NULL 指针,程序可能会出现未定义行为。未定义行为的后果是不可预测的,可能导致程序的正常功能丧失、数据损坏或其他逻辑错误。

示例:

#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int) * 1000);  // 请求内存
    // 忽略malloc失败的检查,继续使用ptr
    ptr[0] = 10;  // 如果malloc失败,ptr会是NULL,这里访问空指针,未定义行为
    return 0;
}
3. 内存泄漏

如果在 malloc 分配内存失败后没有正确处理(如没有及时释放之前分配的内存),可能会导致 内存泄漏。内存泄漏指的是程序在结束时未释放已分配的内存,这会导致程序在运行时消耗更多的内存,最终可能导致系统内存不足或程序崩溃。

示例:

#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int) * 1000);  // 分配内存
    if (ptr == NULL) {
        // malloc失败,未释放之前已分配的内存
        // 忘记释放内存,造成内存泄漏
        return 1;
    }

    // 使用ptr
    free(ptr);  // 应该在使用后释放内存
    return 0;
}
4. 程序的逻辑错误

malloc 失败后,如果没有适当的错误处理,可能导致程序继续运行并且进入错误的执行路径,造成逻辑上的错误,甚至使程序产生错误的输出或行为。

示例:

#include <stdlib.h>
#include <stdio.h>

int main() {
    int* ptr = (int*)malloc(sizeof(int) * 1000);  // 分配内存
    if (ptr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;  // 退出程序,避免继续执行
    }
    
    // 使用ptr
    printf("Memory allocated successfully.\n");
    free(ptr);  // 释放内存
    return 0;
}
5. 影响程序的性能或稳定性

如果 malloc 失败时没有及时处理或报告错误,可能会导致程序在长期运行中因内存不足而性能下降,甚至崩溃。在资源紧张的环境下,频繁的内存分配失败可能会逐步影响程序的稳定性。

解决办法:

1.检查返回值:

        总是检查 malloc 返回的指针是否为 NULL,如果是,则说明内存分配失败。

int* ptr = (int*)malloc(sizeof(int) * 1000);
if (ptr == NULL) {
    // 处理内存分配失败的情况,如打印错误信息并退出程序
    printf("Memory allocation failed!\n");
    exit(1);
}

2.及时释放资源:

        确保在程序退出之前,释放所有动态分配的内存,避免内存泄漏。

3.合理的内存请求:

        避免请求过多的内存,尤其是在内存紧张的环境中,分配超大内存块时应该谨慎。

4.使用异常处理(在 C++ 中):

        如果你使用 C++,可以考虑使用 new 操作符,它在内存分配失败时会抛出 std::bad_alloc 异常,你可以使用异常处理机制来捕获这一异常。

使用 new(C++)示例:

#include <iostream>
#include <new>  // 用于std::bad_alloc

int main() {
    try {
        int* ptr = new int[1000000000];  // 尝试分配大量内存
        // 使用ptr
        delete[] ptr;  // 释放内存
    } catch (std::bad_alloc& e) {
        std::cout << "Memory allocation failed: " << e.what() << std::endl;
    }
    return 0;
}

总结:

        malloc 分配失败时返回 NULL,如果不进行检查并直接使用返回的 NULL 指针,会导致崩溃、未定义行为或内存泄漏等问题。因此,使用 malloc 时必须确保在使用返回的指针之前进行空指针检查,并在内存不再需要时及时释放内存,避免资源浪费。


http://www.kler.cn/a/428899.html

相关文章:

  • elasticsearch基础
  • 蓝桥杯训练—矩形面积交
  • 大语言模型的语境中“越狱”和思维链
  • AUTOSAR从入门到精通-自动驾驶测试技术
  • R语言的文件操作
  • HackMyVM-Klim靶机的测试报告
  • 如何利用Python爬虫获得商品类目
  • ARM寄存器简介
  • 基于单片机的书写坐姿规范提醒器设计(论文+源码)
  • 粉丝生产力与开源 AI 智能名片 2+1 链动模式商城小程序的融合创新与价值拓展
  • PyTorch 本地安装指南:全面支持 macOS 、 Linux 和 Windows 系统
  • wazuh-modules-sca
  • 麒麟 V10 系统(arm64/aarch64)离线安装 docker 和 docker-compose
  • 使用trace-cmd跟踪Linux内核函数:一次愉快的内核探险
  • BurpSuite-7(自动化漏扫)
  • Redis的五种数据类型(Set、Zset)
  • K8s面试系列:K8s常用 API 资源总结速记
  • Redis过期删除(淘汰)策略概念和理解,以及key已过期内存未释放的处理方式
  • Unity控制物体材质球的改变
  • 解决流网络中不存在s~u~t路径的节点的最大流问题
  • 分享一个开源的网络加速器
  • Vue Web开发(三)
  • 前端路径“@/“的使用和配置
  • 【第一篇】逆向实战,exe游戏 逆向实战之某网络游戏---本文仅供学习-仅供学习-----逆向程序-优雅草央千澈-逆向端游实战---逆向某很火很火的游戏实战。
  • 【Linux】WSL:Win运行Linux
  • 【深度学习】利用Java DL4J 构建和训练医疗影像分析模型