从内存角度分析:数组删除自己内部指定对象和通过函数形参改值问题

深入C++对象模型与this指针:内存布局、虚函数与性能优化 在C++编程中,理解对象的内存布局是掌握面向对象核心机制的关键。对象模型定义了编译器如何将类成员映射到内存,涉及内存对齐、成员排列等底层原理,直接影响程序的内存使用效率和缓存局部性。通过虚函数表(vtable)和虚函数指针(vptr)实现的多态机制,是C++运行时动态绑定的技术基础,为设计灵活可扩展的软件架构提供了支持。在工程实践中,合理利用空基类优化(EBO)、避免对象切片、正确使用this指针与智能指针,能显著提升代码的健壮性和性能。本文结合C++对象模型和this指针的深度解析,通过内存布局分析、调试 阅读详情

使用数组的 indexOf() 和 splice 方法来删除内部指定的一个元素

javascript结构:

// 定义一个数组
var arr = [
    {name:'N1'},
    {name:'N2'},
    {name:'N3'}
];

// 找到内部 name 为 N3 的一个对象,删除之
for(var k in arr){
    var item = arr[k];
    if(item.name === "N3"){
        var index = arr.indexOf(item);
        console.log('index ' + index); // 此时可以找到 index 为 2
        arr.splice(index,1); // 删除该项
    }
}

// 检测当前的arr数组
console.log('当前的arr');
console.log(arr); // 此时arr为 [{name:'N1'},{name:'N2'}] 表示删除成功

如下方式,却无法删除:

var cars = [
    {name:'Benz'},
    {name:'BMW'},
    {name:'Tesla'}
];

var item = {name:'BMW'};
var index_cars = cars.indexOf(item);
console.log('index_cars');
console.log(index_cars); // -1 表示没有找到该项,表示没有找到name 为 BMW的项
cars.splice(index_cars,1); // 这里表示从倒数第一项,删除一个,删除的是最后一个
console.log('cars');
console.log(cars); // 此处结果应该是这样 [{name:'Benz'},{name:'BMW'}] 
// (虽然输出形式不是这样的,但意思代表的一样) 这显然不是想要的结果

Why?

上面 var item = {name:'BMW'} 表示在内存中,新生成了一个对象,并不是所要在 cars 数组中找的name 为 BMW的那一项。所以返回 -1 ,两者的内存地址并不一样,并不是一个对象。

现在继续测试一下,下面的情形:

javascript结构:

var fruit =['origin','banana','apple'];
var index_fruit = fruit.indexOf('banana');
console.log('index_fruit');
console.log(index_fruit); // 1
fruit.splice(index_fruit,1); // 删除该项

console.log('fruit');
console.log(fruit); // ["origin", "apple"]

成功找到,删除成功, 这种查找方法对字符串等简单类型的没有内存地址引用的问题。

关于通过函数形参赋值中的问题

var origin = {
    name: 'origin',
    list: [1, 2, 3]
};

// 在函数内部,形参引用赋值,直接改变对象,没有效果 (离开函数作用域之后会被还原)
function change(o) {
    o = 'changed';
}

// 可以改变对象属性的引用
function changeTwo(o) {
    o.name = 'changedTwo';
}

// 即使属性是引用类型,也可以被改变
function changeThree(o) {
    o.list = 'changedThree';
}

change(origin);
console.log(origin); // => { name: 'origin', list: [ 1, 2, 3 ] }

console.log('----------------');

changeTwo(origin);
console.log(origin); // => { name: 'changedTwo', list: [ 1, 2, 3 ] }

console.log('----------------');
changeThree(origin);
console.log(origin); // => { name: 'changedTwo', list: 'changedThree' }

在上面的例子中,无法使用函数来直接修改原对象,因为在函数的内部原对象作为实参被传进去,修改后只针对函数内部的作用域范围,出了函数之外将不起作用。
而在函数内部却可以修改原对象的属性,出了函数作用域之后仍然有效。(不管原对象的属性是简单类型还是引用类型)

总结

针对数组删除一项元素,要注意的是:存在地址引用的复杂类型的元素删除需谨慎,需从内部查找,而如字符串般简单的数据类型的可以直接查找。
注意:数组的indexOf() 方法属于ES5 , 如要全面兼容浏览器需要Polyfill :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

拓展

拓展: Array.indexOf 函数的用法:

https://msdn.microsoft.com/zh-cn/library/bb383831.aspx

论文记录:Affine Formation Maneuver Control of Multiagent Systems 多智能体编队控制仿真记录 实现功能:平移/旋转/尺寸缩放/shear,见截图 注意:本仿真图只是起到了演示效果,中间过程速度产生突变,实际中是不允许的。需要进行速度规划,这一点论文中仿真图更为贴合实际。 参考论文:Zhao, S. (2018). Affine Formation Maneuver Control of Multiagent Systems. IEEE Transactions on Automatic Control, 63(12), 4140–4155. 突然发现有个博主写得很好,参考: 阅读详情

相关推荐

基于STM32智能教室灯光照明人数监测系统

本文设计了一套基于STM32和物联网技术的智能教室照明系统,通过光照传感器和双红外对管实现精准人数统计,结合"光照+人数"双条件判断实现按需照明。系统采用"感知-决策-执行-云联"架构,包含环境感知、人数统计、控制执行等模块,支持本地自动控制和手机APP远程管理。测试表明系统能有效避免"长明灯"现象,具有节能降耗、管理智能化的特点。创新点在于双向人数统计算法和双条件控制逻辑,为智慧校园建设提供了实用解决方案。

1162

C++数据结构与算法从入门到放弃(一):数组(图解+代码)

#写在最前 忽然发现数据结构忘得差不多了,从头开始来一遍,就当是复习QAQ 整点好活数组的定义数组的访问数组的接口在C++上实现 数组的定义 若集合S由n个元素,且各元素之间具有一个线性次序,则可将他们存放于起始地址A、物理位置连续的一段存储空间,并统称作数组(array)。通常以A作为该数组的标识,数组A[]中的每一个元素都唯一对应于某一个下标编号。在绝大多数高级程序设计语言中,一般都是从0开始...

学渣集散地 1227

Unity游戏开发客户端Lua基础

Unity游戏开发客户端面经之 lua 篇

Sea3752的博客 1万+

删除数组的一条数据

1、纯数组 var arr = [ '111' , '222' , '333' , ' 444' , '555' ]2、删除对象数组里面的,一条符合要求的数据。对比两个数组,删除相同的。

程序媛的博客 2787

本地如何安装midscene.js运行环境

手把手教你本地安装midscene.js运行环境

实践助梦想成长 2610

基于yolo11的BGA图像目标检测

15.YOLOv8的n/s版本(如YOLOv8n-1280),或通过TensorRT量化压缩模型。3.使用自适应batch_size(如根据GPU显存动态调整),推荐16-32。为采集分辨率整数倍(如原图2592×1944,训练时缩放为640×480),保持宽高比。14.采用余弦退火学习率(cos_lr)和早停(patience=50),防止过拟合。1.模型标注后,少量标注全部人工校验,大量数据抽检,部分人工检验。13.部署模型后持续收集困难样本(如模棱两可的预测结果),定期迭代更新模型。

qq_47798402的博客 1206

移除元素(数组)

数组在内存地址中是连续的,不能单独地删除数组中某个元素,只能覆盖 最容易想到的方法:暴力解法 public int removeElement(int [] nums,int val){ int n = nums.length; for (int i = 0; i <n ; i++) { //发现需要移除的元素,就将数组集体向前移动一位 if(nums[i]==val){ for (i

CoCo629vanilla的博客 605

2025.06.20【pacbio】|PB甲基化分析结果的统计与可视化介绍

本文介绍了PacBio甲基化数据的统计分析与可视化方法。主要内容包括:1) 分析甲基化位点分布、比例及染色体分布;2) 修饰基序(Motif)的统计与热图展示;3) 全基因组和局部区域测序深度可视化;4) 使用IGV查看单个reads修饰情况。文章提供了R代码示例,涵盖柱状图、分布图、热图等多种可视化形式,并建议了差异甲基化分析等进阶方法,帮助科研人员深入挖掘甲基化数据。

2067

【代码随想录】【数组】移除元素

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。同样地,我们可以使用两个指针分别指向位置 000 和 n−1n-1n−1,每次比较两个指针对应的数,选择较大的那个逆序放入答案并移动指针。给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。元素的顺序可以改变。

?的博客 240

86 arduino 电机yl_(八)arduino入门:直流电机控制

一、本节介绍在本实验中,您将学习如何使用驱动芯片L293D和SunFounder Uno板控制小型直流(DC)电机的方向和速度。为了使初学者更容易,我们将让直流电机左右旋转,自动加速和减速。二、材料准备1 *小型直流电机1 * L293D1 * Arduino Uno板1 *面包板1 * USB数据线杜邦线三、原理讲解L293D这是一个非常实用的芯片,可以独立控制两台直流电机。在这个实验中,只有一...

weixin_29163857的博客 3571

华为OD机试双机位C卷:日志排序 (Py/C/C++/Java/Js/Go)

华为OD机试双机C卷真题【日志排序】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试-日志排序。

qq_45776114的博客 1754

类和对象 [ 深入 ] 类的 6 个默认成员函数

本文系统讲解了C++类的6个默认成员函数,重点关注构造函数、析构函数、拷贝构造函数和赋值运算符重载。详细分析了每个函数的特点、自动生成规则及使用场景:构造函数负责对象初始化,析构函数处理资源释放,拷贝构造函数实现对象拷贝,赋值运算符重载完成对象间赋值。文章通过Date类和Stack类案例,对比了浅拷贝与深拷贝的实现差异,强调了资源管理类必须自定义拷贝构造和赋值重载。此外,还介绍了运算符重载规则、const成员函数作用及取地址运算符重载的特殊应用场景,为理解C++对象生命周期管理提供了全面指导。

Small_entreprene的博客 1293

openclaw本地模型对接

使用是官方推荐的一种集成方式,它可以简化配置过程。但由于您的系统环境和之前复杂的配置历史,我为您梳理了一个核心流程,并增加了关键的“事后检查”步骤,以确保能从根本上解决问题。

suny8的专栏 2463

STL之容器作为形参的传递

眼高手低,一看就会,一写就错,刚刚想起来用容器,结果连怎么传参数都忘了。 参考:  http://blog.youkuaiyun.com/yishaxiaoyao/article/details/44344097 STL中的容器是个神器,第一次接触时,甚是感到C语言好坑,毫无留念的投入到STL。 vect可以理解为数组,这个数组比较特殊,不用考虑长度,溢出等问题,系统都给我们做好

入门记 7310

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

内存的介绍

内存的介绍

西西弗的博客 1151

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

c++杂项

杂项

x13262608581的博客 258

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

堆和栈的区别

1.从存储角度来看,堆内存主要用于存储实例对象和JRE classes,占内存用于存储基本类型变量和对象的引用 2.从存取速度来看,栈存取速度快,堆存取速度比较慢,因为要在运行时动态分配内存,存取速度较慢 3.从线程的角度来看,每个线程都有一个自己的JAVA栈,所有线程共享一个堆。在JVM中,内存被分为线程栈区和堆区 4.从GC看来,栈区GC比较频繁,堆区GC不频...

didui0897的博客 145

C++指针与引用实战:10个案例解析内存访问与生命周期管理

在C++编程中,内存访问是理解程序运行机制的核心。指针和引用作为直接操作内存地址和对象别名的工具,是实现高效、灵活代码的关键。其原理在于,指针存储内存地址,允许间接访问和算术运算;引用则作为对象的别名,提供更安全的直接访问方式。掌握它们的技术价值在于,能够编写出性能更高、资源管理更精细的程序,同时避免悬空指针、内存泄漏等常见问题。应用场景广泛,包括函数参数传递、动态内存管理、数据结构操作以及现代C++智能指针的使用。本文通过10个实战案例,深入剖析指针与引用的内存视角、常见陷阱及智能指针的应用,帮助开发者夯

weixin_34252686的博客 449

内存的理解

1 程序运行为什么需要内存 1.1 计算机程序运行的目的 计算机为什么需要编程?编程已经编了很多年,已经写了很多程序,为什么还需要另外写程序?计算机有这个新的程序到底为了什么? 程序的目的是为了去运行,程序运行是为了得到一定的结果。计算机就是用来计算的,所有的计算机程序其实都是在做计算。计算就是在计算数据。所以计算机程序中很重要的部分就是数据。 计算机程序 = 代码 + 数据。计算...

weixin_43554366的博客 205

C++类和动态内存分配

C++ Primer Plus读书笔记 1.类静态成员 类中可以有一些静态变量,不管这个类创建了多少个对象,这个变量始终都是保持不变的,因为它是静态变量,这就给一些在所有对象中都有相同值的类提供了方便。 在进行类的变量定义时,将数组定义成指针的形式,可以不在定义时就将大小分配,而是在构造函数中使用new对其分配空间。 2.析构函数的调用 析构函数的调用时机: 当在成员函数中

powder_snow的博客 321

程序运行与内存

1.计算机程序运行的目的 程序的目的就是为了运行,程序运行是为了得到一定的结果,程序其实就是在计算数据。 计算机程序 = 代码 + 数据 代码 + 数据(经过运行后) = 结果 另一种理解就是,代码就是动作,就是加工数据的动作,数据就是数字,就是被代码加工的东西。 所以程序运行的目的可得出为:结果、过程。 拿函数类比一下,形参就是待加工的数据,当然还需要一些局部变量(临时数据),函数本体就是代码,函数返回值就是运行结果,函数的执行就是过程。函数的不同,有的函数重在过程,有的函数重在结果,有的函数都看重,

yrmyrnm的博客 685

C语言基础(6)核心:函数完整知识点梳理

文章摘要:本文系统讲解了C语言函数的核心知识点。首先介绍函数的作用:降低耦合性、实现模块化和代码复用。详细说明函数定义、调用、声明的语法规则,分析值传递机制和栈调用的底层原理。重点讲解递归函数的设计要点,包括递归出口设置、问题规模递减等,并给出阶乘和斐波那契数列的经典示例。最后阐述数组作为函数参数的传递规则,以及变量作用域、生命周期等关键概念,帮助读者全面掌握C语言函数的应用技巧和底层机制。

Xoeman_31的博客 517

C++面试核心:内存管理、多态与STL容器深度解析

在C++编程中,内存管理是开发者必须掌握的核心概念,它直接关系到程序的稳定性和性能。通过理解new/delete与malloc/free的本质区别,以及智能指针(如shared_ptr、unique_ptr)的引用计数与所有权模型,可以有效避免内存泄漏和悬空指针问题。这些原理不仅体现了RAII(资源获取即初始化)的设计哲学,也为构建高可靠性的系统软件提供了基础。在实际工程中,结合虚函数表(vtable)实现的多态机制,使得面向对象设计更加灵活,而标准模板库(STL)提供的vector、map等容器,则通过优

weixin_30892889的博客 355

22/1/8 C++和C语言的区别及程序调试

(重点部分,序号用加粗斜体标出)

Jessica_Shao的博客 904

C++参数传递机制深度解析:从值、引用到移动语义的底层原理与实战选择

在C++编程中,参数传递是函数与外部世界交换数据的核心机制,直接关系到程序的内存管理、性能表现和代码安全性。其底层原理本质上是数据访问方式的抉择:是通过创建副本的“传值”方式,还是通过传递内存地址的“传引用”方式。从技术价值看,不同的传递方式在性能开销、数据安全性和表达意图上存在显著差异。传值提供了数据隔离性,但可能带来昂贵的拷贝成本;传引用则通过别名机制避免了拷贝,提升了效率,但需警惕悬空引用和意外修改的风险。在实际应用场景中,对于内置类型和小型POD结构体,传值是简单安全的选择;而对于大型对象或需要避免

weixin_30614109的博客 606

java第三部分 起始于string截至到内部类

首先将teststudent类的字节码文件调入方法区,然后main函数进栈开始执行,执行第一行代码时,zi的字节码文件,及其父类fu的字节码文件 ,以及fu的父类object类的字节码(进入顺序是先父类再子类)都会进入方法区,创建zi类对象时,对象区域分为两块,一块是zi自己的属性,一块是fu的属性,之后通过z.访问zi对象的属性时,首先到zi自己的属性中去找,找不到就到fu的属性中去找。执行第二行时,会到静态区中寻找name和teachername,但是name找不到,因为他不是静态变量,于是出错。

wr319714471的博客 229
上一篇: angular中定义服务的三种方式
下一篇: angular 中一些常用的小方法之详解API
Wang's Blog
博客等级 码龄12年 7433粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值