43 C 程序动态内存分配:内存区域划分、void 指针、内存分配相关函数(malloc、calloc、realloc、_msize、free)、内存泄漏
目录
1 C 程序内存区域划分
1.1 代码区 (Code Section)
1.2 全局/静态区 (Global/Static Section)
1.3 栈区 (Stack Section)
1.4 堆区 (Heap Section)
1.5 动态内存分配
2 void 指针(无类型指针)
2.1 void 指针介绍
2.2 void 指针的作用
2.3 void 指针的特点
2.4 void 指针类型转换注意事项
2.4.1 其他类型指针赋给 void 指针
2.4.2 void 指针赋给其他类型指针
3 malloc() 函数
3.1 函数原型
3.2 使用步骤
3.3 动态分配整型数据的空间
3.4 动态分配数组空间
4 calloc() 函数
4.1 函数原型
4.2 使用步骤
4.3 案例演示
5 realloc() 与 _msize 函数
5.1 函数原型
5.2 使用步骤
5.3 案例演示
6 内存泄漏与 free() 函数
6.1 内存泄漏
6.2 free() 函数
6.2.1 函数原型
6.2.2 使用步骤
6.2.3 注意事项
6.2.4 案例演示
7 内存分配的基本原则
7.1 避免分配大量的小内存块
7.2 仅在需要时分配内存
7.3 总是确保释放已分配的内存
8 综合案例
1 C 程序内存区域划分
在 C 语言中,内存可以分为几个不同的区域,每个区域都有其特定的作用。

1.1 代码区 (Code Section)
也称为文本区,是只读的,用于存放程序的机器指令。
这个区域的内容是在程序编译时确定的,并且在程序运行期间不会改变。
1.2 全局/静态区 (Global/Static Section)
这个区域用于存储全局变量和静态变量。
全局变量是在所有函数外部定义的变量,它们在整个程序的生命周期内都存在。
静态变量可以在全局或局部范围内定义,但无论在哪里定义,它们都会在这个区域分配空间,并且在整个程序执行过程中保持存在。
初始化的全局变量和静态变量会被分配到已初始化的数据段(如 .data 段),而未初始化的全局变量和静态变量则会被分配到未初始化的数据段(如 .bss 段)。
1.3 栈区 (Stack Section)
栈区用于存储函数的局部变量和函数调用信息(如返回地址)。
当一个函数被调用时,一个新的栈帧(stack frame)会被创建并压入栈顶,其中包含了该函数所有局部变量。
函数执行完毕后,这个栈帧会被弹出栈,释放了该函数使用的内存。
栈区的操作是自动化的,由编译器管理,不需要程序员手动干预。
1.4 堆区 (Heap Section)
堆区是一个动态分配内存的区域,通常通过 malloc()、calloc()、realloc() 和 free() 等函数进行管理。
动态内存分配允许程序在运行时请求任意大小的内存块,这对于处理未知大小的数据集非常有用。
一旦不再需要这块内存,应该调用 free() 函数释放它,以避免内存泄漏。
1.5 动态内存分配
动态内存分配是指在程序运行时根据需要从堆区请求内存的行为。
由于动态分配的内存没有与任何变量名关联,因此必须使用指针来访问这些内存。
使用动态内存分配时,程序员需要负责确保正确地分配和释放内存,以防止内存泄漏或其他错误。
2 void 指针(无类型指针)
2.1 void 指针介绍
在 C 语言中,void 指针是一种特殊的指针类型,它可以指向任何类型的数据。C99 标准允许定义一个类型为 void 的指针变量,这种指针在编译时没有具体的类型信息,因此可以灵活地用于各种场景。
2.2 void 指针的作用
灵活性:指针变量必须有类型,以便编译器知道如何解释内存块中的二进制数据。然而,在某些情况下,当向系统请求内存时,可能还不确定会有什么类型的数据写入内存。此时,可先使用void指针获取内存块(仅含地址信息,无类型信息),待后续使用时再明确数据类型。
通用性:void 指针在函数参数传递和通用数据处理中非常有用,尤其是在实现泛型编程时,可以避免重复编写针对不同数据类型的代码。
2.3 void 指针的特点
类型转换:void 指针与其他所有类型的指针之间可以互相转换。任一类型的指针都可以转换为 void 指针,而 void 指针也可以转换为任一类型的指针。
解引用限制:由于 void 指针没有具体的类型信息,因此不能直接使用 * 运算符(解引用)来访问它所指向的值。如果需要访问 void 指针指向的数据,必须先将其转换为适当的类型指针。
#include <stdio.h>int main()
{int num = 42;double pi = 3.14159;// 将 int 指针隐式转换为 void 指针void *viPtr = #// 将 double 指针隐式转换为 void 指针void *vdPtr = π// 将 void 指针转换为 int 指针并解引用// int *intPtr = viPtr; // 隐式类型转换int *intPtr = (int *)viPtr; // 显示类型转换printf("整数值:%d\n", *intPtr); // 42// 将 void 指针转换为 double 指针并解引用// double *doublePtr = vdPtr; // 隐式类型转换double *doublePtr = (double *)vdPtr; // 显示类型转换printf("浮点数:%f\n", *doublePtr); // 3.141590// void 指针不能直接解引用,会导致编译错误// 下面的代码会报错// printf("%d\n", *viPtr);// printf("%f\n", *vdPtr);// 如果需要访问 void 指针指向的数据,必须先将其转换为适当的类型指针printf("%d\n", *(int *)viPtr); // 42printf("%f\n", *(double *)vdPtr); // 3.141590return 0;
}
2.4 void 指针类型转换注意事项
2.4.1 其他类型指针赋给 void 指针
将其他类型指针赋给 void 指针时,可以使用隐式转换,因为 void 指针不包含指向的数据类型的信息,通常是安全的。
int num = 42;
double pi = 3.14159;// 将 int 指针隐式转换为 void 指针
void *viPtr = #// 将 double 指针隐式转换为 void 指针
void *vdPtr = π
2.4.2 void 指针赋给其他类型指针
将 void 指针赋给其他类型指针时,建议使用显式类型转换,这样更加安全。如果使用隐式类型转换,有些编译器会触发警告。
// 将 void 指针显式转换为 int 指针并解引用
int *intPtr = (int *)viPtr;
printf("整数值:%d\n", *intPtr);// 将 void 指针显式转换为 double 指针并解引用
double *doublePtr = (double *)vdPtr;
printf("浮点数:%f\n", *doublePtr);
3 malloc() 函数
3.1 函数原型
malloc() 函数用于在程序运行时动态分配一块连续的内存空间。这是 C 语言中常用的动态内存分配函数之一,通常与 free() 函数一起使用,以确保内存的正确管理和释放。
#include <stdlib.h>
void *malloc(size_t size);
- size:要分配的内存块的大小,以字节为单位
- 如果内存分配成功,返回一个 void 指针,指向新分配内存块的起始地址。
- 如果内存分配失败(例如内存不足),返回一个空指针 NULL。
3.2 使用步骤
- 分配内存:调用 malloc() 函数,传入所需的内存大小。
- 检查返回值:检查返回的指针是否为 NULL,以确保内存分配成功。
- 使用内存:将返回的 void 指针转换为适当的类型指针,并使用该指针访问分配的内存。
- 释放内存:使用 free() 函数释放分配的内存,以避免内存泄漏。
3.3 动态分配整型数据的空间
#include <stdio.h>
#include <stdlib.h>int main()
{// 在栈区直接创建局部变量int num = 120;int *p = NULL;// 动态分配整型数据的空间// malloc(sizeof(int)) 请求分配一个 int 类型大小的内存块// (int *) 是显式类型转换,将 void 指针转换为 int 指针// p 指向新分配内存块的起始地址p = (int *)malloc(sizeof(int));// 检查内存是否分配成功if (p == NULL){printf("内存分配失败\n");return 1; // 退出程序}// p = # 不要这样操作,这相当于修改了指针 p 的指向,就没有用到上面动态分配的空间// 使用解引用赋值并输出*p = num;printf("p指向的地址(堆区):%p\n", (void *)p);printf("局部变量num的地址(栈区):%p\n", (void *)&num);printf("p指向的值:%d\n", *p); // 120// 释放分配的内存,避免内存泄漏// free(p); // 简单处理// 推荐处理if (p != NULL){free(p);p = NULL; // 释放后将指针设为 NULL,避免悬挂指针}return 0;
}
输出结果如下所示:

3.4 动态分配数组空间
在 C 语言中,malloc() 函数不仅可用于分配单个变量的内存,还可以用于动态分配数组的内存。以下是一个示例,展示了如何使用 malloc() 函数动态分配整型数组的内存,并对其进行操作。
#include <stdio.h>
#include <stdlib.h>int main()
{int *p = NULL; // 定义整型指针int n = 5; // 定义数组长度// int array[n]; 错误,表达式必须含有常量值// 动态分配内存,将地址赋给指针 p// malloc(n * sizeof(int)) 请求分配一个大小为 n * sizeof(int) 的内存块,即 n 个 int 类型的内存// (int *) 是显式类型转换,将 void 指针转换为 int 指针// p 指向新分配内存块的起始地址p = (int *)malloc(n * sizeof(int));// 判断是否分配成功if (p == NULL){printf("内存分配失败\n");return 1; // 退出程序}// 给数组元素赋值for (int i = 0; i < n; i++){p[i] = i * 10;}// 输出数组的元素for (int i = 0; i < n; i++){printf("p[%d] = %d\n", i, p[i]);}// 释放分配的内存,避免内存泄漏// free(p); // 简单处理// 推荐处理if (p != NULL){free(p);p = NULL; // 释放后将指针设为 NULL,避免悬挂指针}return 0;
}
输出结果如下所示:

4 calloc() 函数
4.1 函数原型
calloc() 函数用于在程序运行时动态分配内存,并将分配的内存初始化为零。这是 C 语言中常用的动态内存分配函数之一,通常与 free() 函数一起使用,以确保内存的正确管理和释放。
#include <stdlib.h>
void *calloc(size_t numElements, size_t sizeOfElement);
- numElements:要分配的元素的数量。
- sizeOfElement:每个元素的大小(以字节为单位)。
- 如果内存分配成功,返回一个 void 指针,指向新分配内存块的起始地址。
- 如果内存分配失败(例如内存不足),返回一个空指针 NULL。
4.2 使用步骤
- 分配内存:调用 calloc() 函数,传入所需的元素数量和每个元素的大小。
- 检查返回值:检查返回的指针是否为 NULL,以确保内存分配成功。
- 使用内存:将返回的 void 指针转换为适当的类型指针,并使用该指针访问分配的内存。
- 释放内存:使用 free() 函数释放分配的内存,以避免内存泄漏。
4.3 案例演示
以下是一个示例代码,展示了如何使用 calloc() 函数动态分配整型数组的内存,并将其初始化为零:
#include <stdio.h>
#include <stdlib.h>int main()
{int *p = NULL; // 定义整型指针int n = 5; // 定义数组长度// 动态分配内存并初始化为零,将地址赋给指针 p// calloc(n, sizeof(int)) 请求分配一个大小为 n * sizeof(int) 的内存块,并将每个字节初始化为零// (int *) 是显式类型转换,将 void 指针转换为 int 指针p = (int *)calloc(n, sizeof(int));// 判断是否分配成功if (p == NULL){printf("内存分配失败\n");return 1; // 退出程序}// 输出数组的元素的值for (int i = 0; i < n; i++){printf("p[%d] = %d\n", i, p[i]); // 全是 0}// 给数组元素赋值for (int i = 0; i < n; i++){p[i] = i * 10;}// 输出数组的元素for (int i = 0; i < n; i++){printf("p[%d] = %d\n", i, p[i]); // 0 10 20 30 40}// 释放分配的内存,避免内存泄漏// free(p); // 简单处理// 推荐处理if (p != NULL){free(p);p = NULL; // 释放后将指针设为 NULL,避免悬挂指针}return 0;
}
输出结果如下所示:

5 realloc() 与 _msize 函数
5.1 函数原型
realloc() 函数用于重新分配 malloc() 或 calloc() 函数所获得的内存块的大小。这在需要动态调整内存大小时非常有用。
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
- ptr:要重新分配的内存块的指针。
- size:新的内存块的大小(以字节为单位)。
- 返回一个指向重新分配内存块的指针。如果内存重新分配成功,返回的指针可能与原始指针相同,也可能不同。
- 如果内存分配失败,返回一个空指针 NULL。
- 如果在原内存块上进行缩减,通常返回的地址与原来的地址相同。
5.2 使用步骤
- 分配内存:使用 malloc() 或 calloc() 函数分配初始内存。
- 重新分配内存:调用 realloc() 函数,传入当前指针和新的内存大小。
- 检查返回值:检查返回的指针是否为 NULL,以确保内存重新分配成功。
- 使用新的内存:使用返回的新指针访问重新分配的内存。
- 释放内存:使用 free() 函数释放分配的内存,以避免内存泄漏。
5.3 案例演示
以下是一个示例代码,展示了如何使用 realloc() 函数动态调整内存大小,并使用 _msize() 函数获取指定内存块的大小:
_msize() 函数用于获取指定内存块的大小,但请注意,这个函数不是标准 C 库的一部分,而是特定于某些平台(如 Windows)。在其他平台上,可能需要使用其他方法来获取内存块的大小。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>int main()
{// 声明指针int *p = NULL;// 分配内存// 使用 malloc() 函数分配初始内存,大小为 100 * sizeof(int)p = (int *)malloc(sizeof(int) * 100);if (p == NULL){printf("初始内存分配失败\n");return 1;}// 使用 _msize() 函数获取分配的内存大小,并输出指针地址和内存大小printf("p=%p, size:%zu 字节\n", p, _msize(p)); // 400// 调整内存大小p = (int *)realloc(p, sizeof(int) * 2000);if (p == NULL){printf("内存重新分配失败\n");return 1;}// 使用 _msize() 函数获取分配的内存大小,并输出指针地址和内存大小printf("p=%p, size:%zu 字节\n", p, _msize(p)); // 8000// 再次调整内存大小// 如果在原内存块上进行缩减,通常返回的地址与原来的地址相同p = (int *)realloc(p, sizeof(int) * 200);if (p == NULL){printf("内存重新分配失败\n");return 1;}// 使用 _msize() 函数获取分配的内存大小,并输出指针地址和内存大小printf("p=%p, size:%zu 字节\n", p, _msize(p)); // 800// 释放分配的内存,避免内存泄漏// free(p); // 简单处理// 推荐处理if (p != NULL){free(p);p = NULL; // 释放后将指针设为 NULL,避免悬挂指针}return 0;
}
输出结果如下所示:

6 内存泄漏与 free() 函数
6.1 内存泄漏
内存泄漏是指在程序运行过程中,动态分配的内存空间没有被正确释放,导致系统中的可用内存逐渐减少,直到耗尽系统可用的内存资源。内存泄漏不仅会影响程序的性能,还可能导致程序崩溃或系统不稳定。
6.2 free() 函数
6.2.1 函数原型
free() 函数用于释放动态分配的内存,以便将内存返回给操作系统,防止内存泄漏。
void free(void *ptr);
- ptr:指向要释放的内存块的指针。ptr 必须是通过 malloc()、calloc() 或 realloc() 动态分配的内存块地址。
- free() 函数没有返回值。
6.2.2 使用步骤
- 分配内存:使用 malloc()、calloc() 或 realloc() 函数动态分配内存。
- 使用内存:在程序中使用分配的内存。
- 释放内存:使用 free() 函数释放分配的内存,确保内存返回给操作系统。
6.2.3 注意事项
1. 避免双重释放:
释放的内存块一旦被 free() 释放,就不应该再次操作已经释放的地址,也不应该再次使用 free() 对该地址释放第二次。这会导致未定义行为,可能会导致程序崩溃。
int *p = (int *)malloc(sizeof(int));
free(p); // 第一次释放
free(p); // 错误:第二次释放
2. 避免内存泄漏:
如果忘记调用 free() 函数,会导致无法访问未回收的内存块,构成内存泄漏。
int *p = (int *)malloc(sizeof(int));
// 忘记释放内存
// free(p); // 应该在这里释放内存
3. 检查指针是否为 NULL:
在释放内存之前,最好检查指针是否为 NULL。释放 NULL 指针是安全的,不会导致错误,但这是一个良好的编程习惯。
释放内存后,最好将指针设为 NULL,以避免悬挂指针(即指向已释放内存的指针)。
int *p = (int *)malloc(sizeof(int));
if (p != NULL) {free(p);p = NULL; // 释放后将指针设为 NULL,避免悬挂指针
}
6.2.4 案例演示
以下是一个示例代码,展示了如何正确使用 malloc() 和 free() 函数,避免内存泄漏和双重释放:
#include <stdio.h>
#include <stdlib.h>int main() {int *p = NULL; // 定义整型指针// 动态分配内存p = (int *)malloc(sizeof(int));if (p == NULL) {printf("内存分配失败\n");return 1;}// 使用分配的内存*p = 120;printf("p指向的地址:%p\n", (void *)p);printf("p指向的值:%d\n", *p);// 释放分配的内存if (p != NULL) {free(p);p = NULL; // 释放后将指针设为 NULL}return 0;
}
7 内存分配的基本原则
在 C 语言中,动态内存分配是一项重要的任务,合理的内存管理可以提高程序的性能和稳定性。以下是一些内存分配的基本原则:
7.1 避免分配大量的小内存块
原因:分配堆上的内存有一些系统开销,包括分配和释放内存时的管理开销。分配许多小的内存块会增加这些开销,从而影响程序的性能。
建议:尽量合并多个小内存块的分配,使用较大的内存块来减少系统开销。例如,可以预先分配一个较大的缓冲区,然后在需要时从中划分出所需的小内存块。
7.2 仅在需要时分配内存
原因:动态分配的内存会占用系统的资源,如果分配了不必要的内存,不仅浪费资源,还可能导致内存泄漏。
建议:在实际需要使用内存时再进行分配,并且在使用完内存后及时释放。避免过早分配内存或分配过多的内存。
7.3 总是确保释放已分配的内存
原因:未释放的内存会导致内存泄漏,随着时间的推移,内存泄漏会逐渐消耗系统资源,最终可能导致程序崩溃或系统不稳定。
建议:在编写分配内存的代码时,就要确定好在代码的什么地方释放内存。使用 free() 函数释放不再需要的内存,并确保不会对同一个内存块多次释放。
#include <stdio.h>
#include <stdlib.h>// 分配和释放内存的辅助函数
void allocate_and_use_memory() {int *p = NULL;// 仅在需要时分配内存p = (int *)malloc(sizeof(int) * 1000);if (p == NULL) {printf("内存分配失败\n");return;}// 使用分配的内存for (int i = 0; i < 1000; i++) {p[i] = i * 10;}// 输出部分元素for (int i = 0; i < 10; i++) {printf("p[%d] = %d\n", i, p[i]);}// 及时释放内存if (p != NULL){free(p);p = NULL; // 释放后将指针设为 NULL,避免悬挂指针}
}int main() {// 调用内存管理函数allocate_and_use_memory();return 0;
}
8 综合案例
动态创建数组,输入 5 个学生的成绩,再定义一个函数检测成绩低于 60 分的,输出不合格的成绩。
#include <stdlib.h>
#include <stdio.h>// 函数原型声明
void check(int *);int main()
{int *p = NULL;// 在堆区开辟一个 5 * 4 的空间,用于存储 5 个整数p = (int *)malloc(5 * sizeof(int));// 检查内存是否分配成功if (p == NULL){printf("内存分配失败\n");return 1; // 退出程序}printf("请输入5个成绩(整数):");// 从用户输入读取 5 个整数,存储到动态分配的内存中for (int i = 0; i < 5; i++){// scanf("%d", p + i); // 使用指针算术,将输入的整数存储到 p[i] 中// p + i 是指针算术,表示将指针 p 向后移动 i 个元素的位置scanf("%d", &p[i]); // 使用数组形式,将输入的整数存储到 p[i] 中// &p[i] 是取地址操作,表示 p 指向的数组中第 i 个元素的地址}// 调用 check 函数,检查不及格的成绩check(p);// 释放动态分配的内存,避免内存泄漏free(p);p = NULL; // 避免悬挂指针return 0;
}// 函数定义
void check(int *p)
{printf("不及格的成绩有: ");// 遍历动态分配的内存中的 5 个整数for (int i = 0; i < 5; i++){// 如果成绩小于 60,输出该成绩if (p[i] < 60){printf(" %d ", p[i]);}}
}
输出结果如下所示:

相关文章:
43 C 程序动态内存分配:内存区域划分、void 指针、内存分配相关函数(malloc、calloc、realloc、_msize、free)、内存泄漏
目录 1 C 程序内存区域划分 1.1 代码区 (Code Section) 1.2 全局/静态区 (Global/Static Section) 1.3 栈区 (Stack Section) 1.4 堆区 (Heap Section) 1.5 动态内存分配 2 void 指针(无类型指针) 2.1 void 指针介绍 2.2 void 指针的作用 2.3 …...
编译链接的过程发生了什么?
一:程序的翻译环境和执行环境 在 ANSI C 的任何一种实现中,存在两个不同的环境。 第 1 种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第 2 种是执行环境,它用于实际执行代码 也就是说:↓ 1࿱…...
【D3.js in Action 3 精译_028】3.4 小节 DIY 实战:使用 Observable 在线绘制 D3 条形图
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可…...
【Linux】 TCP短服务编写和守护进程
文章目录 TCP 短服务编写流程进程组和会话和守护进程 TCP 短服务编写流程 TCP服务器是面向连接的,客户端在发送数据之前需要先与服务器建立连接。 因此,TCP服务器需要能够监听客户端的连接请求。为了实现这一功能,需要将TCP服务器创建的套接字…...
自学数据库-MYSQL
自学数据库-MYSQL 一.表和视图1.表1.1 表创建1.2 索引1.2.1 这里是废话,不感兴趣的可以直接更具目录的跳过这里的内容1.2.1.1 索引是什么1.2.1.2 相关数据结构:二叉树、红黑树、B-Tree、BTree、Hash…①普通索引②唯一索引③全文索引④组合索引 1.3 表数据操作(更新…...
机器学习——多模态学习
多模态学习:机器学习领域的新视野 引言 多模态学习(Multimodal Learning)是机器学习中的一个前沿领域,它涉及处理和整合来自多个数据模式(如图像、文本、音频等)的信息。随着深度学习的蓬勃发展࿰…...
ceph掉电后无法启动osd,pgs unknown
处理办法: 只有1个osd,单副本,掉电损坏osd,只能考虑重建pg,丢失部分数据了。生产环境务必考虑2,3副本设计。避免掉电故障风险。 掉电后osdmap丢失无法启动osd的解决方案 - 武汉-磨渣 - 博客园 https://zhuanlan.zhih…...
HTML5实现古典音乐网站源码模板1
文章目录 1.设计来源1.1 网站首页1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面2.效果和源码2.1 动态效果2.2 源代码源码下载万套模板,程序开发,在线开发,在线沟通作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/142…...
快速生成单元测试
1. Squaretest插件 2. 依赖 <dependency><groupId>junit</groupId>...
WebGL系列教程十一(光照原理及Blinn Phong着色模型)
快速导航(持续更新中) WebGL系列教程一(开篇) WebGL系列教程二(环境搭建及着色器初始化) WebGL系列教程三(使用缓冲区绘制三角形) WebGL系列教程四(绘制彩色三角形&…...
《ASP.NET Web Forms 实现短视频点赞功能的完整示例》
在现代Web开发中,实现一个动态的点赞功能是非常常见的需求。本文将详细介绍如何在ASP.NET Web Forms中实现一个视频点赞功能,包括前端页面的展示和后端的处理逻辑。我们将确保点赞数量能够实时更新,而无需刷新整个页面。 技术栈 ASP.NET We…...
Linux SSH服务
Linux SSH(Secure Shell)服务是一种安全的远程登录协议,用于在Linux操作系统上远程登录和执行命令。它提供了加密的通信通道,可以在不安全的网络环境中安全地进行远程访问。 SSH服务在Linux系统中通常使用OpenSSH软件包来实现。它…...
MySQL--视图(详解)
目录 一、前言二、视图2.1概念2.2语法2.3创建视图2.3.1目的 2.4查看视图2.5修改数据2.5.1通过真实表修改数据,会影响视图2.5.2通过修改视图,会影响基表 2.6注意2.7 删除视图2.8 视图的优点 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&…...
Javascript 普通非async函数调用async函数
假设我们有一个异步函数 async function asyncFunction() {console.log("开始执行异步函数");await new Promise(resolve > setTimeout(resolve, 1000)); // 模拟异步操作console.log("异步函数执行完毕"); } 我们在调用这个异步函数时,比…...
【LeetCode】修炼之路-0004-Median of Two Sorted Arrays【python】
题目 Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be O(log (mn)). Example 1: Input: nums1 [1,3], nums2 [2] Output: 2.00000 Explanation: merged…...
C++面试速通宝典——10
177. #include <filename> 和 #include "filname.h" 有什么区别? 对于 #include <filename> , 编译器从标准库路径开始搜索 filename.h。 对于 #include "filename.h,编译器从用户的工作…...
肺腺癌预后新指标:全切片图像中三级淋巴结构密度的自动化量化|文献精析·24-10-09
小罗碎碎念 本期这篇文章,我去年分享过一次。当时发表在知乎上,没有标记参考文献,配图的清晰度也不够,并且分析的还不透彻,所以趁着国庆假期重新分析一下。 这篇文章的标题为《Computerized tertiary lymphoid structu…...
基于jmeter+perfmon的稳定性测试记录
1. 引子 最近承接了项目中一些性能测试的任务,因此决定记录一下,将测试的过程和一些心得收录下来。 说起来性能测试算是软件测试行业内,有些特殊的部分。这部分的测试活动,与传统的测试任务差别是比较大的,也比较依赖…...
前沿论文 M5Product 组会 PPT
对比学习(Contrast learning):对比学习是一种自监督学习方法,用于在没有标签的情况下,通过让模型学习哪些数据点相似或不同来学习数据集的一般特征。假设一个试图理解世界的新生婴儿。在家里,假设有两只猫和…...
navicat~导出数据库密码
当我们mysql密码忘记了,而在navicat里有记录,我们应该如何导出这个密码呢? 第一步:文件菜单,导出链接,导出连接获取到 connections.ncx 文件 这里需要勾选 导出密码!!! 不然导出的文…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
