C语言详解(动态内存管理)2
Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
💥💥个人主页:奋斗的小羊
💥💥所属专栏:C语言
🚀本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。
目录
- 前言
- 1、常见动态内存错误
- 1.1 对NULL指针的解引用操作
- 1.2 对动态内存空间的越界访问
- 1.3 对非动态开辟内存使用free释放
- 1.4 使用free释放动态内存的一部分
- 1.5 对同一快动态内存多次释放
- 1.6 动态开辟内存忘记释放(内存泄漏)
- 2、动态内存经典笔试题分析
- 2.1 题目一
- 2.2 题目二
- 2.3 题目三
- 2.4 题目四
- 3、柔性数组
- 3.1 什么是柔性数组
- 3.2 柔性数组的特点
- 3.3 柔性数组的使用
- 3.4 柔性数组的优势
- 总结

前言
总的来说,动态内存管理为我们提供了更加灵活、高效和可扩展的内存管理方式,但动态内存管理函数可能会带来一些风险,主要包括内存泄漏、内存溢出和野指针等问题,我们在使用动态内存管理函数时要多留心,避免风险的出现
1、常见动态内存错误
1.1 对NULL指针的解引用操作
如果我们写的代码不严谨,没有考虑到动态内存分配失败的可能,就会写出类似于下面的代码:
#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(10 * sizeof(int));//直接使用指针pint i = 0;for (i = 0; i < 10; i++){p[i] = i + 1;}return 0;
}
这样的代码可能并没有什么问题,但是存在很大的隐患,因为动态内存函数是有可能开辟内存空间失败的,当开辟失败时会返回NULL,而NULL指针是不能解引用的
像VS这样比较强大的编译器会立马检测到并提示你

为了避免这种错误,我们需要对指针p进行判断,再决定是否使用
#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(10 * sizeof(int));//判断p是否为空指针if (p == NULL){//打印出错误信息perror("malloc");//终止程序return 1;}int i = 0;for (i = 0; i < 10; i++){p[i] = i + 1;}return 0;
}
1.2 对动态内存空间的越界访问
我们用动态内存函数开辟多大的空间,我们就使用多大的空间,不能越界访问,例如:
#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(10 * sizeof(int));//判断p是否为空指针if (p == NULL){//打印出错误信息perror("malloc");//终止程序return 1;}int i = 0;//p+1跳过1个整型,p+10就会越界for (i = 0; i <= 10; i++){p[i] = i + 1;}return 0;
}
聪明的VS也会检测出错误提示你

1.3 对非动态开辟内存使用free释放
free函数是用来释放由动态内存函数开辟的空间的,不能释放普通内存
#include <stdio.h>
#include <stdlib.h>int main()
{int arr[10] = { 0 };int* p = arr;free(p);p = NULL;return 0;
}
当我们运行起来后就出问题了

1.4 使用free释放动态内存的一部分
上面我们用malloc函数申请了10个整型空间,然后通过for循环给这10个整型空间内放1~10的整数,有些同学可能会为了方便这样写代码:
#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(10 * sizeof(int));//判断p是否为空指针if (p == NULL){//打印出错误信息perror("malloc");//终止程序return 1;}//给申请的动态空间内存1~10int i = 0;for (i = 0; i < 5; i++){*p++ = i;}//释放动态内存空间free(p);p = NULL;return 0;
}
当我们运行起来才发现写出了BUG

这又是为什么呢?
事实上此时free(p)中的p指针已经不再指向malloc开辟的动态内存的起始地址了,因为*p++这里对p的指向不断递增
free操作的指针必须指向要被释放的动态内存的起始地址
1.5 对同一快动态内存多次释放
当我们用完一块动态内存空间后不再使用对其释放后,可能会因为忘记而重复释放一次,并且如果第一次释放时忘记给p指针赋NULL,那么程序就会出错
//使用...//释放动态空间free(p);//...free(p);p = NULL;return 0;
但是如果我们两次释放时都给p指针赋了NULL,那基本不会发生什么事,相当于没有错,只是逻辑上讲不通
所以,在我们用free释放完动态内存空间后,紧跟着对指针赋NULL是很有必要的
1.6 动态开辟内存忘记释放(内存泄漏)
动态开辟的空间一定要释放,并且正确释放
当我们写代码的时候,存在这样一种可能会出现的错误,那就是动态开辟的内存忘记释放或者因为某些原因还没有到free语句就提前终止代码,这里举个简单的例子
#include <stdio.h>
#include <stdlib.h>void text()
{int flag = 1;int* p = (int*)malloc(100);if (p == NULL){return 1;}//使用//因为某些原因函数提前返回了if (flag == 1){return;}//free函数free(p);p = NULL;
}int main()
{//自定义函数text();//后面还有大量代码//....return 0;
}
虽然我们确实用了free函数释放空间,但是当代码量较大时可能会因为某些原因还没到free函数就提前终止了,而我们还没意识到,就算后面我们意识到了这个问题这块内存我们也找不到了
只有整个程序结束后这块内存才能被释放,如果程序一直不结束这块空间就再也找不到了,这就叫内存泄漏
所以,就算动态内存申请使用后用了
free,也是有可能犯内存泄漏的错误,我们要多加小心
内存泄漏是比较可怕的,尤其是某些24小时不断运行的服务器程序,如果存在内存泄漏,内存被耗干也只是时间的问题
2、动态内存经典笔试题分析
2.1 题目一
请问运行下面 text函数会有什么后果?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_memory(char* p)
{p = (char*)malloc(100);
}void text(void)
{char* str = NULL;get_memory(str);strcpy(str, "hello world");printf(str);
}int main()
{text();return 0;
}
上面的代码一共有两个问题
第一个问题:malloc申请动态内存空间后没有使用free函数释放,这可能会导致内存泄漏
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_memory(char* p)
{p = (char*)malloc(100);
}void text(void)
{char* str = NULL;get_memory(str);strcpy(str, "hello world");printf(str);free(str);str = NULL;
}int main()
{text();return 0;
}
第二个问题: 函数传参传值调用和传址调用使用错误
这个代码的意思是申请一块动态内存空间地址交给指针p,通过指针p再交给指针str,再使用strcpy函数将字符串拷贝到动态内存空间内,最后打印出字符串
但是get_memory函数传参的时候使用的是传值调用,所以指针p跟指针str没有关系
有两种纠错方法
方法一: 将传值调用改为传址调用,此时p为二级指针
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_memory(char** p)
{*p = (char*)malloc(100);
}void text(void)
{char* str = NULL;get_memory(&str);strcpy(str, "hello world");printf(str);free(str);str = NULL;
}int main()
{text();return 0;
}

方法二: 直接返回指针p的地址,不需要传参
char* get_memory()
{char* p = (char*)malloc(100);return p;
}void text(void)
{char* str = NULL;str = get_memory();strcpy(str, "hello world");printf(str);free(str);str = NULL;
}int main()
{text();return 0;
}

2.2 题目二
请问运行下面 text函数会有什么后果?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>char* get_memory(void)
{char p[] = "hello world";return p;
}void text(void)
{char* str = NULL;str = get_memory();printf(str);
}int main()
{text();return 0;
}
上面的代码是一个非常经典的例子,之前在C语言(指针)3中野指针一小节介绍过类似的例子
上面代码的问题:
我们在自定义函数get_memory中创建了一个局部临时数组存入字符串“hello world”,再将字符串的首地址返回用指针str接收,虽然此时指针str确实指向字符串“hello world”的首地址,但是此时str是没有权限访问这块空间的
因为在局部数组p在出了get_memory函数后就销毁了,它申请的空间会被收回,即使指针str能找到这块空间,但是它已经没有权限使用了,此时str就是一个野指针

所以我们应该避免返回栈空间地址
想要改正上面的代码也很简单,我们申请一块动态内存就行,同时也别忘了释放
#include <stdio.h>
#include <stdlib.h>
#include <string.h>char* get_memory(void)
{char* p = (char*)malloc(20);strcpy(p, "hello world");return p;
}void text(void)
{char* str = NULL;str = get_memory();printf(str);free(str);str = NULL;
}int main()
{text();return 0;
}
2.3 题目三
请问运行下面 text函数会有什么后果?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_memory(char** p, size_t num)
{*p = (char*)malloc(num);
}void test(void)
{char* str = NULL;get_memory(&str, 100);strcpy(str, "hello world");printf(str);
}int main()
{test();return 0;
}
上面的代码是可以打印出“hello world”的,但是遗憾的是上面的代码中使用了动态内存函数malloc,但是没有使用free函数释放动态内存空间
虽然上面的代码可以实现我们想要的效果,但这样的代码是存在安全隐患的
动态内存开辟函数
malloc、calloc、realloc和动态内存释放函数free必须成对出现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_memory(char** p, size_t num)
{*p = (char*)malloc(num);
}void test(void)
{char* str = NULL;get_memory(&str, 100);strcpy(str, "hello");printf(str);free(str);str = NULL;
}int main()
{test();return 0;
}
2.4 题目四
请问运行下面 text函数会有什么后果?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void test(void)
{char* str = (char*)malloc(100);strcpy(str, "hello");free(str);if (str != NULL){strcpy(str, "world");printf(str);}
}int main()
{test();return 0;
}
使用malloc函数申请一块100个字节大小的动态内存空间放入字符串“hello”,然后使用free函数释放这一动态内存空间
但是此时指针str中还存着我们开辟的动态内存空间的地址,正确的写法free函数后应紧跟str = NULL;,但是上面的代码并没有这一条语句
当if语句判断的时候指针str确实是不为空指针的,进入if语句后执行strcpy(str, "world");这条代码,根据我们对strcpy函数的了解,这里还要对指针str解引用,但是指针str我们之前已经用free函数释放过了,并且没有赋NULL,所以str此时是野指针不能解引用,运行起来程序就会出错

这道题考察的还是free函数后紧跟p = NULL的问题
3、柔性数组
3.1 什么是柔性数组
C99中,结构体中的最后一个成员允许是未知大小的数组,这就叫柔性数组成员
- 在结构体中
- 最后一个成员
- 未知大小的数组
struct S1
{int n;char c;double d;int arr[];//未知大小的数组
};
struct S2
{int n;char c;double d;int arr[0];//未知大小的数组
};
上面两种写法中arr都是柔性数组成员
有些编译器可能只支持其中的一种写法,VS中两种写法都支持
3.2 柔性数组的特点
- 结构中的柔性数组成员前面必须至少有一个其他成员
sizeof返回的这种结构大小不包含柔性数组的内存- 包含柔性数组成员的结构用
malloc函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

正是因为sizeof返回的这种结构大小不包含柔性数组的内存,所以结构中的柔性数组成员前面必须至少有一个其他成员,否则结构体的大小没法计算
3.3 柔性数组的使用
包含柔性数组的结构怎么使用呢?
包含柔性数组的结构创建变量不会像一般结构那样创建,而是使用malloc函数进行内存的动态分配
#include <stdio.h>
#include <stdlib.h>struct S
{int n;int arr[];
};int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + 20 * sizeof(int));if (ps == NULL){perror("malloc");//终止程序return;}//使用空间ps->n = 100;int i = 0;for (i = 0; i < 20; i++){ps->arr[i] = i + 1;}//...free(ps);ps = NULL;return 0;
}

柔性数组的柔性怎么体现呢?
因为上面包含柔性数组的结构是由malloc函数进行内存的动态分配,所以我们可以使用realloc函数进行动态内存的调整,那这个数组的大小就可大可小
#include <stdio.h>
#include <stdlib.h>struct S
{int n;int arr[];
};int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + 20 * sizeof(int));if (ps == NULL){perror("malloc");//终止程序return 1;}//使用空间ps->n = 100;int i = 0;for (i = 0; i < 20; i++){ps->arr[i] = i + 1;}//调整ps指向的空间大小struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 40 * sizeof(int));//进行指针的非空判断,保护原地址if (ptr != NULL){ps = ptr;//防止ptr变成野指针ptr = NULL;}else{perror("realloc");//终止程序return 1;}for (i = 0; i < 40; i++){printf("%d ", ps->arr[i]);}//...free(ps);ps = NULL;return 0;
}

如果不使用柔性数组,还有一种办法能实现上面的效果
#include <stdio.h>
#include <stdlib.h>struct S
{int n;int* arr;
};int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));if (ps == NULL){perror("malloc");return 1;}int* tmp = (int*)malloc(20 * sizeof(int));if (tmp == NULL){perror("malloc");return 1;}else{ps->arr = tmp;tmp = NULL;}ps->n = 100;int i = 0;//给指针arr指向的20个整型空间赋值for (i = 0; i < 20; i++){ps->arr[i] = i + 1;}//调整指针arr指向的空间大小tmp = (int*)realloc(ps->arr, 40 * sizeof(int));if (tmp != NULL){ps->arr = tmp;tmp = NULL;}else{perror("realloc");return 1;}for (i = 0; i < 40; i++){printf("%d ", ps->arr[i]);}//...free(ps->arr);ps->arr = NULL;free(ps);ps = NULL;return 0;
}

结构struct S中有一个指针成员,我们的想法是用malloc函数申请一块动态内存空间,再让结构中的这个指针指向这块动态分配的内存,然后这块由指针指向的动态内存空间就可以用realloc函数进行大小的调整了
可以看到这样实现的效果和柔性数组相似,那柔性数组为什么还要存在呢?
其实相比之下柔性数组还是有它的优势的
3.4 柔性数组的优势
- 方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了两次内存分配,并把整个结构体返回给用户,用户调佣free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事
所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存释放
- 这样有利于访问速度
连续的内存有利于提高访问速度,也有利于减少内存碎片
因为malloc等动态内存函数在申请空间时会在堆区允许的地方申请一块连续的空间,但是动态内存函数申请的多个动态内存空间之间并不是连续的,这些空间之间就形成了内存碎片
总结
- 动态内存管理是一把双刃剑,它能给我们提供灵活的内存管理方式,但同样也会带来风险
- 检查动态内存分配是否成功:在使用动态内存管理函数时,应该检查分配内存是否成功,以确保程序正常运行,这是比较容易忽略的点
相关文章:
C语言详解(动态内存管理)2
Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…...
【ubuntu软件版本管理】利用update-alternatives管理ubuntu软件
我们有的时候希望在安装了新软件之后保留旧版本的软件,比如希望保留旧版本的gcc,以防以前写的C编译出问题,这时候就需要版本管理软件update-alternatives。 在此之前我们需要先弄清楚,什么是ubuntu的软件?拿C源…...
如何把linux安装到单片机中
1.如何把linux安装到单片机中 将Linux安装到单片机中通常不是一个直接的过程,因为单片机(如51系列、STC系列等)的硬件资源和处理能力有限,而Linux是一个为更强大硬件平台(如个人电脑、服务器)设计的操作系…...
Ubuntu bash按Table不联想
Ubuntu bash按Table不联想 bash-completion包未安装或损坏: 自动补全功能依赖于bash-completion包。首先,需要确保这个包已经安装。可以通过下面的命令安装或重新安装它: sudo apt install --reinstall bash-completion安装完成后,…...
Xcode中给UIView在xib中添加可视化的属性
给UIView在xib中添加可视化的属性 效果如下图: 可以直接设置view 的 borderColor 、borderWidth、cornerRadius,也可以单独指定view的某个角是圆角。减少了代码中的属性。 完整代码: UIViewBorder.h #import <UIKit/UIKit.h>inter…...
中缀表达式和前缀后缀
在中缀表达式中,操作数可能与两个操作符相结合 但是,想要不带括号无歧义,且不需要考虑运算符优先级和结合性 所以考虑 前缀表达式,波兰表达式 后缀表达式 逆波兰表达式 对于人来说,中缀表达式是最容易读懂的。但是对于…...
强化学习面试题
强化学习面试题通常会涵盖该领域的多个方面,包括基本概念、算法、应用以及实践问题。以下是一些常见的强化学习面试题及其简要回答: 基本概念题: 什么是强化学习? 强化学习是一种通过智能体与环境交互来学习最优行为策略的机器学习范式。智能体根据当前状态选择动作,环境…...
Pytorch中的广播机制
一、广播(broadcast)机制概述 在PyTorch中,广播机制(Broadcast)允许对不同形状的张量执行逐元素操作,而无需显式地复制数据。这一机制使得编写代码更加简洁和高效。广播机制遵循一定的规则来扩展较小的张量,使其与较大的张量具有相同的形状 …...
2024年全国一高考数学压轴题
(3) 证明: 显然, 等差数列 { a 1 , . . . , a 4 n 2 } \{a_{1},...,a_{4n2}\} {a1,...,a4n2} 是 ( i , j ) (i, j) (i,j)-可分的等价于等差数列 { 1 , . . . , 4 n 2 } \{1,...,4n2\} {1,...,4n2} 是 ( i , j ) (i,j) (i,j)-可分的. 前推后显然, 我们考虑后推前, 在去…...
springboot+vue前后端项目接口校验通信数据完整性
方案:使用国密SM3算法实现数字签名 服务端 maven的pom文件引用 <!-- 国密算法支持 --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.69</version><…...
进程通信(IPC-Inter Process Communication)
进程之间的通信通过内核空间实现 IPC技术 ①管道(匿名管道/命名管道-FIFO队列) ②System V IPC(消息队列、信号量和共享内存) ③套接字(UNIX套接字&Internet套接字) ※信号 软中断,信号提供了一种处理异步事件的方法,作为进程通信的一种机制&am…...
idea debug时提示”Method breakpoints may dramatically slow down debugging“的解决办法
问题现象 今天同事喊我过去看一个问题,项目正常启动的时候没问题,debug模式就卡住了,很久不动。我推测是哪个断点导致的,一看断点果然有情况。在方法上打了断点。 解决方式(Android Studio一样的解决) 1、View Brea…...
计算机缺失msvcp100.dll如何解决?教你5种简单高效的修复方法
在现代科技发展的时代,计算机已经成为我们生活和工作中不可或缺的工具。然而,在使用计算机的过程中,我们常常会遇到各种问题和困扰。其中之一就是计算机找不到msvcp100.dll文件。这个问题可能会给我们的生活和工作带来很多不便,下…...
对硬盘的设想2:纸存,硬指针,软指针
“纸存”是设想中的存储器,它只能改写两次:写一次,再改一次,然后就不能再动了。就像拿着钢笔在纸上写字一样,所以叫纸存。 硬指针P、软指针S S abcd S aPcdPx P aPcdPx S aycd ①一个软指针S,指向数据abcd…...
Python在股票交易分析中的应用:布林带与K线图的实战回测
引言 在股票交易的世界中,技术分析是投资者们用来预测市场动向的重要工具。布林带(Bollinger Bands)作为一种动态波动范围指标,因其直观性和实用性而广受欢迎。本文将通过Python代码,展示如何使用布林带结合K线图来分…...
现代密码学-认证、消息认证码
什么是单向散列函数 单向散列函数(one way hash function):一个输入:消息(message),一个固定长度的输出(散列值,hash value),根据散列值检查消息完整性(integrity) 单向散列函数也称为消息摘要…...
在Java中为什么对a赋值为10,在进行a++时还是等于10呢
首先我们看这样一组代码 public class demo1 {public static void main(String[] args) {int a10;aa;System.out.println(a);} } 结果:10不是在第二步有a操作吗?为什么还是10呢? a的执行步骤如下: 保存当前a的值(即10…...
免费数据库同步软件
在信息化日益发展的今天,数据同步成为了企业和个人用户不可或缺的一部分。数据库同步软件作为数据同步的重要工具,能够帮助我们实现不同数据库系统之间的数据复制和同步,确保数据的一致性和完整性。本文将介绍几款免费数据库同步软件…...
如何轻松修改Windows远程连接的端口号
为了增强远程连接的安全性,最好修改默认的远程桌面协议(RDP)端口号。以下步骤将指导您如何修改Windows注册表中的端口设置,并相应地更新防火墙规则。 一、修改注册表中的端口号 打开注册表编辑器: 按下Win R键&#…...
Leetcode 54. 螺旋矩阵(二维数组移动坐标)
54. 螺旋矩阵 使用vis数组记录该位置是否已经被访问 定义一个int型dir来记录方向,0123分别代表右下左上 当越界或碰壁已访问的位置后,修改dir并计算下一个位置 否则根据原dir计算下一个位置 class Solution {public List<Integer> spiralOrder(i…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...

