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

【C语言】动态内存管理(malloc,free,calloc,realloc详解 )

🦄个人主页:小米里的大麦-CSDN博客

🎏所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html

🎁代码托管:C语言: C语言方向(基础知识和应用) (gitee.com)

⚙️操作环境:Visual Studio 2022

目录

一、引言

二、malloc

1. 简介

2. 语法

3. 使用方法

4. 关于内存的使用(重点)

工作原理:

示例一: malloc(sizeof(int))

示例二: malloc(20)

重要点:

5. 结论

三、free

1. 简介

2. 语法

3. 使用方法

4. 注意事项

 1. 只释放一次

2. 检查指针是否为 NULL

3. 避免悬挂指针

4. 动态数组的处理

5. 释放结构体中的指针

四、calloc

1. 简介

2. 语法

3. 使用方法

4. 注意事项

五、realloc

1. 简介

2. 语法

3. 使用方法

4. 注意事项

5. 缩容的语法和基本用法

缩容注意事项

realloc缩容的工作原理

缩容的实际应用场景

总结

六、总结

共勉


一、引言

动态内存管理是C语言中一个重要的部分,它允许程序在运行时动态地分配、使用和释放内存资源。这篇博客将详细讲解C语言中的四个核心函数:mallocfreecallocrealloc,并讨论它们的使用方法和注意事项。

二、malloc

1. 简介

malloc(memory allocation)用于动态分配指定大小的内存块。它从堆中分配内存,并返回指向该内存块的指针。分配的内存内容未初始化。(malloc - C++ Reference)

2. 语法

#include <stdlib.h>//头文件
void* malloc(size_t size);//函数原型
  • size_t 是一个无符号整数类型,用来表示对象的大小。
  • size 参数指定要分配的内存字节数。
  • 如果成功分配内存,则 malloc 返回指向这块内存的指针;如果失败(例如没有足够的可用内存),则返回 NULL

3. 使用方法

#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int*)malloc(sizeof(int) * 10); // 分配能存储10个int类型元素的内存if (p == NULL) {printf("内存分配失败\n");return 1;}// 使用分配的内存for (int i = 0; i < 10; i++) {p[i] = i;printf("%d ", p[i]);}// 释放内存free(p);return 0;
}
分配内存:
#include <stdio.h>
#include <stdlib.h>int main() {int *p;p = (int *)malloc(sizeof(int));  // 分配一个 int 类型大小的内存if (p == NULL) {printf("内存分配失败!\n");return 1;}*p = 10;  // 给分配的内存赋值printf("值: %d\n", *p);  // 输出值free(p);  // 释放内存return 0;
}
分配多个元素:
#include <stdio.h>
#include <stdlib.h>int main() {int *p;size_t num_elements = 5;p = (int *)malloc(num_elements * sizeof(int));if (p == NULL) {printf("内存分配失败!\n");return 1;}for (int i = 0; i < num_elements; i++) {p[i] = i + 1;}for (int i = 0; i < num_elements; i++) {printf("%d ", p[i]);}printf("\n");free(p);return 0;
}
#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int*)malloc(sizeof(int)); // 分配4字节内存char *q = (char*)malloc(20);        // 分配20字节内存if (p == NULL || q == NULL) {printf("内存分配失败\n");return 1;}*p = 100; // 存储一个int类型的值for (int i = 0; i < 20; i++) {q[i] = 'A'; // 使用分配的20字节空间}// 当你尝试访问 q[20](第21字节)时,程序行为未定义,可能会崩溃// q[20] = 'B'; // **不要这样做**,因为它会导致未定义行为printf("p: %d\n", *p);printf("q: %.20s\n", q);free(p); // 释放分配的内存free(q);return 0;
}

4. 关于内存的使用(重点)

  • 内存对齐:

实际上,malloc 不仅分配请求的字节数,还会考虑内存对齐的要求。这意味着它可能分配比你请求的更多的内存,以便确保内存地址能够适当地对齐。例如,如果系统要求int对齐到4字节边界,那么malloc在分配内存时,会确保返回的地址是4的倍数。如果当前的内存块不满足对齐要求,malloc可能会跳过一些字节(称为填充字节),以找到一个符合对齐要求的位置。

  • 内存碎片:

内存管理库会试图高效地管理内存,避免碎片化。意味着它可能会保留一些额外的内存,以备将来分配使用,但这不是用户直接控制的。

工作原理:

示例一: malloc(sizeof(int))
  • sizeof(int)通常为4(这取决于具体的系统和编译器),意味着malloc(sizeof(int))分配了4字节的内存。
  • malloc(sizeof(int))的返回值是一个指向这4字节内存块的指针。程序可以通过这个指针来存储和访问一个int类型的变量。
  • 总结malloc(sizeof(int))一次性分配了4字节的内存供程序使用。
示例二: malloc(20)
  • 当你调用malloc(20)时,内存管理器(通常由操作系统或运行时库管理)会在堆中找到一块足够大的、至少有20字节的空闲内存块,一次性分配给程序使用(将其分配给你)
  • 分配的20字节内存块起始地址由malloc返回,返回的指针指向这段20字节的内存块,你可以在这块内存上存储数据,但只能使用这20字节的空间。
  • 一旦这块内存分配给你,你就完全拥有了这20字节的空间,程序可以自由地在这个范围内操作。
  • 内存管理:如果你需要更多的空间,你需要手动调用realloc来调整这块内存的大小,或者分配一块新的、更大的内存块。

重要点

  • 一次性分配malloc(20)一次性从堆中分配20字节的内存。这20字节的内存是连续的,并且可以立即使用。
  • 使用限制:这20字节的内存并不会像“用一点给一点”那样逐渐分配,而是一次性分配。如果在使用过程中超过了这20字节的边界(例如试图访问第21字节),则可能会引发未定义行为,通常会导致程序崩溃或内存损坏。
  • 不会自动扩展malloc(20)分配的内存是固定的20字节。如果这20字节的空间用完了,程序必须手动使用realloc来扩展内存块,否则无法存储更多的数据。malloc本身不会自动再给20字节空间。

5. 结论

  • malloc是一次性分配:不管你请求多少字节,malloc都会一次性分配指定数量的内存给你,供你自由使用。
  • 内存不会自动扩展:一旦分配完内存,除非你使用realloc,否则内存块大小固定,不会自动增长。
  • 边界检查:在使用分配的内存时,必须确保不超出已分配的范围,否则会导致程序崩溃或数据损坏。
  • 内存对齐:malloc不仅分配你请求的内存量,还会考虑对齐要求,因此可能会分配比请求的更多的内存。其返回的内存地址会满足特定的对齐要求,确保高效且安全的内存访问。尽管你可能请求了例如malloc(20),实际分配的内存可能会大于20字节,以确保内存对齐,但对你而言,能安全使用的仍然是请求的20字节空间。

三、free

1. 简介

free用于释放由malloccallocrealloc分配的内存,使这部分内存重新可用。(手动释放内存)(free - C++ Reference)

2. 语法

#include <stdlib.h>//头文件
void free(void *ptr);//函数原型
ptr: 是一个指向要释放的内存块的指针。如果 ptr 是 NULL,free 不做任何操作。

3. 使用方法

free的使用非常简单,以下是一个例子:

int *p = (int*)malloc(sizeof(int) * 10);
if (p != NULL) {// 使用内存free(p); // 释放内存
}

4. 注意事项

 1. 只释放一次

  • 不要对同一块内存多次调用 free。这会导致未定义行为,比如程序崩溃。
  • 不要对未分配的内存调用 free。确保你只释放通过 malloccalloc, 或 realloc 分配的内存。

2. 检查指针是否为 NULL

在调用 free 之前检查指针是否为 NULL:
if (p != NULL) {free(p);p = NULL; // 避免悬挂指针
}

3. 避免悬挂指针

当释放内存后,通常将指针设置为 NULL 来避免悬挂指针问题。
这样可以防止意外地再次尝试释放相同的内存。
free(p);
p = NULL;

4. 动态数组的处理

如果使用 malloc 或 calloc 分配了数组,释放内存时也需要正确处理:
int *arr = (int *)malloc(10 * sizeof(int));
...
free(arr);
arr = NULL;

5. 释放结构体中的指针

如果结构体中包含指向动态分配内存的指针,在销毁结构体前需要释放这些内存:
struct Node {int data;struct Node *next;
};void freeNode(struct Node *node) {if (node != NULL) {freeNode(node->next); // 递归释放链表中的每个节点free(node);}
}

正确使用 free 函数是良好编程实践的一部分,它可以避免内存泄漏,并确保程序的稳定性和性能。

四、calloc

1. 简介

calloc(contiguous allocation)用于分配内存并初始化所有位为零。与malloc不同,它接受两个参数:分配的元素个数每个元素的大小。(calloc - C++ Reference)

2. 语法

#include <stdlib.h>//头文件
void* calloc(size_t num, size_t size);//函数原型

参数说明

  • num:需要分配的元素数量。
  • size:每个元素的大小(以字节为单位)。

返回值

  • 如果内存分配成功,则返回指向新分配内存的指针。
  • 如果内存分配失败,则返回NULL

3. 使用方法

calloc()函数为所请求的元素数量分配一个连续的内存块,并且初始化所有元素为零值。意味着对于基本数据类型如int, float, 或者char等,所有元素都会被设置为0。

#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int*)calloc(10, sizeof(int)); // 分配能存储10个int类型元素的内存,并初始化为0if (p == NULL) {printf("内存分配失败\n");return 1;}// 使用分配的内存for (int i = 0; i < 10; i++) {printf("%d ", p[i]);}// 释放内存free(p);return 0;
}

4. 注意事项

  • malloc相似,calloc返回的指针也应检查是否为NULL
  • 使用完动态分配的内存后,必须调用free释放内存。

与 malloc 的区别

  • malloc()只分配内存但不初始化。
  • calloc()不仅分配内存,还会初始化所有元素为零值。
  • calloc()接受两个参数:元素个数和单个元素的大小;而malloc()仅接受一个参数:总大小。
如果你需要分配一段内存并且希望该内存被自动初始化为零,那么calloc()是一个更好的选择。
如果你只需要分配内存而不关心初始化,或者需要更灵活地控制内存大小,那么malloc()可能更适合。这里有一个简单的例子来展示calloc()和malloc()的区别:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {int *array_calloc, *array_malloc;//array:数组int n = 5;// 使用 callocarray_calloc = (int *) calloc(n, sizeof(int));if (array_calloc == NULL) {printf("calloc failed\n");return 1;}for (int i = 0; i < n; i++) {printf("calloc[%d]: %d\n", i, array_calloc[i]);}free(array_calloc);// 使用 mallocarray_malloc = (int *) malloc(n * sizeof(int));if (array_malloc == NULL) {printf("malloc failed\n");return 1;}memset(array_malloc, 0, n * sizeof(int));  // 手动初始化为零for (int i = 0; i < n; i++) {printf("malloc[%d]: %d\n", i, array_malloc[i]);}free(array_malloc);return 0;
}

五、realloc

1. 简介

realloc(reallocation)在 C 语言中用于改变已分配内存块的大小。这个函数允许您动态地增加或减少内存空间的大小,这对于需要根据运行时条件调整数据结构大小的应用程序非常有用。它可以扩展或缩小内存块,如果新大小大于旧大小,未初始化的新内存内容是不确定的。(realloc - C++ Reference)

2. 语法

#include <stdlib.h>//头文件
void* realloc(void *ptr, size_t size);//函数原型
  • ptr: 指向要重新分配的内存块的指针(先前通过malloccallocrealloc分配的内存块的指针)。如果 ptr 是 NULL,那么 realloc() 将执行与 malloc(size) 相同的操作。
  • size: 新的内存大小(以字节为单位)。如果 size 为 0 并且 ptr 不是 NULL,那么 realloc() 将释放 ptr 指向的内存块,并返回一个 NULL 值。
  • 返回值:realloc() 返回一个指向新内存块的指针。如果内存重新分配成功,则返回的新指针可能与原来的指针不同。如果失败,它将返回 NULL。如果size为0,则相当于调用free(ptr),并返回NULL

3. 使用方法

以下是一个简单的例子:

#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int*)malloc(sizeof(int) * 5); // 初始分配5个int类型元素的内存if (p == NULL) {printf("内存分配失败\n");return 1;}// 扩展内存到10个int类型元素p = (int*)realloc(p, sizeof(int) * 10);if (p == NULL) {printf("内存重新分配失败\n");return 1;}// 使用扩展的内存for (int i = 0; i < 10; i++) {p[i] = i;printf("%d ", p[i]);}// 释放内存free(p);return 0;
}

4. 注意事项

  • realloc的返回值应检查是否为NULL,因为重新分配可能失败。
  • 如果realloc失败,原来的内存块仍然有效,应该避免内存泄漏
  • 如果新大小为0,realloc等同于调用free

5. 缩容的语法和基本用法

语法不变,同 realloc 的函数原型。

缩容注意事项

1. 数据保留:

  • 如果新的大小大于或等于原始大小,那么原始数据会被保留。
  • 如果新的大小小于原始大小,那么原始数据中超出新大小范围的部分将被丢弃。
  • 因此,在缩小内存之前,最好先备份重要数据,以防丢失。

2. 检查返回值:

  • 总是要检查 realloc() 的返回值是否为 NULL,这表示内存分配失败。
  • 如果返回值非 NULL,则需要将指针更新为新的地址。

3. 类型转换:

  • 类型转换通常需要应用到 realloc() 的返回值上,以保持类型安全。

4. 性能考虑:

  • 频繁缩容可能导致内存碎片化和性能降低。
  • 如果知道内存大小变化频繁,考虑使用其他数据结构或者技术,如自定义内存池。
以下是一个示例代码,展示了如何使用 realloc() 缩小内存大小:
#include <stdio.h>
#include <stdlib.h>int main() {int *array;int n = 10;int new_n;// 分配初始内存array = (int *) malloc(n * sizeof(int));if (array == NULL) {printf("Memory allocation failed!\n");return 1;}// 初始化数组for (int i = 0; i < n; i++) {array[i] = i + 1;}// 打印初始数组printf("Initial array:\n");for (int i = 0; i < n; i++) {printf("%d ", array[i]);}printf("\n");// 缩小内存new_n = 5;array = (int *) realloc(array, new_n * sizeof(int));if (array == NULL) {printf("Memory reallocation failed!\n");free(array);return 1;}// 打印缩容后的数组printf("Reduced array:\n");for (int i = 0; i < new_n; i++) {printf("%d ", array[i]);}printf("\n");// 释放内存free(array);return 0;
}
在这个例子中,原始数组大小为 10,之后通过 realloc() 将其大小减小到了 5。
注意,缩容后只打印了前五个元素,这是因为原始数据中的后五个元素已经不再存在于新的内存块中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {char *p = (char*)malloc(20 * sizeof(char)); // 分配20字节内存if (p == NULL) {printf("内存分配失败\n");return 1;}strcpy(p, "Hello, World!"); // 向内存块中写入字符串// 缩小内存块到10字节p = (char*)realloc(p, 10 * sizeof(char));if (p == NULL) {printf("内存重新分配失败\n");return 1;}printf("缩容后的内容: %s\n", p); // 输出可能出现意外的内容free(p); // 释放内存return 0;
}
代码解析:初始时,我们分配了20字节的内存并存储了字符串"Hello, World!"。
然后,我们使用realloc将内存块缩小到10字节。此时,只能保证前10字节的数据被保留。
由于字符串"Hello, World!"超过了10字节,后面的部分可能被裁剪或者造成字符串结尾缺失。打印时,由于没有足够的空间保存完整的字符串以及字符串的终止符\0,因此可能会出现意外的输出(未定义行为)。

realloc缩容的工作原理

当你使用realloc缩减内存块的大小时(即size比原来分配的大小小),其行为如下:

  1. 数据保留realloc会保留内存块起始位置的一部分内容,保留的部分大小为size(new_size)。换句话说,缩容后的内存块中,前size字节的数据会保留并保持不变。

  2. 释放多余内存:对于超出size范围的多余内存,realloc会将其释放。具体的释放方式取决于内存管理器的实现,但对程序员来说,这部分内存块将不再可用,不能访问和使用。

  3. 指针返回:如果缩容后的内存块可以在原始地址上处理,那么realloc会直接返回原指针。如果内存管理器为了效率或其他原因在缩容过程中移动了内存块,realloc将返回一个新的内存地址,并且会将原来ptr指向的内容复制到新地址。

缩容的实际应用场景

缩容操作常用于以下场景:

  • 内存优化:在动态数据结构(如可变大小数组、缓冲区)中,随着数据量减少,使用realloc来释放多余的内存空间。
  • 节省资源:在程序运行中,及时缩减不再需要的内存块大小,可以节省系统资源,特别是在嵌入式系统或内存受限的环境中。

总结

通过合理使用realloc缩容,可以有效管理程序的内存资源,确保程序在执行过程中占用最小的内存空间,同时保持灵活性和高效性。

  • 在缩小内存时,一定要确保新大小能够容纳必要的数据。
  • 使用 realloc() 缩容时,必须检查返回值是否为 NULL
  • 对于经常需要改变大小的情况,考虑使用更高效的数据结构或内存管理策略。

六、总结

动态内存管理是C语言编程中不可或缺的一部分,正确使用mallocfreecallocrealloc可以提高程序的灵活性和效率。以下是一些关键点:

  • 始终检查内存分配函数的返回值是否为NULL
  • 使用完动态内存后,一定要释放内存,防止内存泄漏。
  • 对于复杂的数据结构,确保正确释放所有分配的内存,以避免内存泄漏和悬空指针。

掌握这些基本函数和相关注意事项,可以帮助你编写出更健壮和高效的C程序。希望这篇博客能帮助你更好地理解和使用C语言中的动态内存管理!

共勉

相关文章:

【C语言】动态内存管理(malloc,free,calloc,realloc详解 )

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html &#x1f381;代码托管:C语言: C语言方向&#xff08;基础知识和应用&#xff09; (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、…...

如何寻找数值仿真参数最优解?CFD参数优化详解3来袭

本期文章将通过2个简单案例演示参数优化的操作步骤&#xff0c;一起来看看吧&#xff01; 流程自动化 实现 CFD 参数优化&#xff0c;首先要创建流程自动化。用户可采用SimLab的Python宏命令&#xff0c;录制建模流程。或在HyperWorks CFD模块的Template Manager创建Tcl/Tk命令…...

虚拟机macos中构建llvm、clang并配置Xcode

安装虚拟机macos&#xff0c;并安装brew&#xff1a; 安装vmware&#xff1a;https://www.bilibili.com/video/BV1Wo4y1E7fc/安装最新版的macos&#xff1a;极限苹果-Mac论坛-提供Mac软件和macOS苹果系统镜像下载下载并安装brew&#xff1a;版本要低&#xff0c;我装的是4.3.5…...

Java 中的 @SneakyThrows 注解详解:简化异常处理的利与弊

在 Java 开发中&#xff0c;异常处理是一个不可避免的重要部分。我们经常需要处理各种检查型异常&#xff08;checked exceptions&#xff09;&#xff0c;这有时会导致代码变得冗长且难以维护。为了简化异常处理&#xff0c;Lombok 提供了一个强大的注解——SneakyThrows。本文…...

系统编程 day11 进程(线程)3

fork函数的总结&#xff1a; 总结对进程学习之中的回收函数wait wait函数&#xff1a; 1.获取子进程的退出状态 2.回收资源------会让僵尸态的子进程销毁 注&#xff1a;1.wait函数本身是一个阻塞操作&#xff0c;会使调用者阻塞 2.父进程要获得子进程的退出状态 子进程&…...

[ Python 原理分析 ]如何实现用户实现博客文章点赞-物联网Python

目录 一、前言 二、Python爬虫 三、详细操作 3.1 建立基本工程 3.2 获取文章列表 3.2.1 找到获取文章请求 3.2.2 分析获取请求 3.2.3 构建获取请求 3.2.4 调试打印 3.3 实现点赞操作 3.3.1 判断点赞状态 3.3.2 找到点赞请求 3.2.3 分析点赞请求 3.2.4 构建点赞请…...

【47 Pandas+Pyecharts | 杭州二手房数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 过滤数据2.3 行政区处理2.4 地址处理2.5 房屋信息处理2.6 面积处理2.7 楼层处理2.8 年份处理2.9 房价处理2.10 删除不用的列2.11 数据类型转换2.12 查看…...

C++入门基础知识13

C 的关键字&#xff08;接上一篇博文&#xff09;&#xff01;&#xff01; 10. const_cast用法&#xff1a; 该运算符用来修改类型的 const 或 volatile 属性。除了 const 或 volatile 修饰之外&#xff0c; type_id 和 expression 的类型是一样的。常量指针被转化成非常量指针…...

IP地址证如何实现HTTPS访问?(内网IP、公网IP)

IP地址证书&#xff08;全称为IP地址的SSL/TLS证书&#xff09;是实现通过IP地址进行HTTPS访问的关键。以下是实现这一目标的详细步骤&#xff1a; 一、选择证书颁发机构&#xff08;CA&#xff09; 1.选择支持IP证书的CA&#xff1a;并非所有证书颁发机构都提供为IP地址颁…...

东土科技车规级网络芯片获批量应用

东土科技孵化的我国第一颗国产汽车芯片名录的车规级TSN交换网络芯片&#xff0c;于近期获得国家新能源汽车技术创新中心10万片芯片订单&#xff0c;将规模化应用于车载网关&#xff0c;赋能新一代自主可控汽车网络通信架构。 车规级TSN交换网络芯片于2021年流片成功&#xff0…...

nvidia系列教程-AGX-Orin pcie扩展M.2磁盘调试笔记

目录 前言 一、AGX-Orin pcie接口介绍 二、原理图连接 三、SDK配置 四、M.2磁盘调试 总结 前言 NVIDIA Jetson AGX Orin 是一款强大的嵌入式平台,广泛应用于 AI 推理、机器人和自动驾驶等领域。在扩展存储方面,PCIe 接口的 M.2 SSD 是一个常见的选择。本篇博客将记录如何…...

haproxy七层代理知识点以及各种配置

1.为什么用haproxy 当后端主机有一个出现问题了的时候&#xff0c;我们需要访问的流量全部打到正常工作的后端主机&#xff0c;所以我们需要后端检测&#xff0c;lvs没有后端检测&#xff0c;所以就需要用到haproxy 2.负载均衡 2.1 什么是负载均衡 负载均衡&#xff0c;Loa…...

uniapp自定义浮动图标、列表布局

uniapp自定义浮动图标 <button class="fab" @click="goPage"><image src="../../../static/yiyuan.png" mode="" style="width: 60rpx;height:60rpx;"></image></button>.fab {z-index: 100;positi…...

学习嵌入式入门(十)高级定时器简介及实验(下)

一、高级定时器互补输出带死区控制实验 上图中&#xff0c;CH1 输出黄色的 PWM&#xff0c;它的互补通道 CH1N 输出绿色的 PWM。通过对比&#xff0c;可以 知道这两个 PWM 刚好是反过来的&#xff0c;CH1 的 PWM 为高电平期间&#xff0c;CH1N 的 PWM 则是低电平&#xff0c; 反…...

使用python在不改变原有excel的格式下,修改指定单元格格式

需求 有一个账单&#xff0c;需要生成一个副本&#xff0c;但是需要将交易员列隐藏&#xff0c;不能改变原有的格式 xlsx的文件容易实现&#xff0c;使用openpyxl实现 xls的文件使用xlrdxlutil实现 参考了https://segmentfault.com/q/1010000008270267 class GenCopyReport(o…...

MySQL数据库:详细安装与配置指南

目录 背景: 一.下载过程(MySQL数据库): 二.安装过程(MySQL数据库)&#xff1a; 三.验证MySQL是否安装成功 背景: MySQL 是一个流行的开源关系数据库管理(RDBMS)&#xff0c;由瑞典MySQL AB公司开发&#xff0c;后俩该公司被Sun Microsystems收购&#xff0c;Sun Microsyste…...

python爬虫代理IP实战

Python爬虫代理IP实战指南 在进行网络爬虫时&#xff0c;使用代理IP可以有效隐藏真实IP地址&#xff0c;避免被目标网站封禁。本文将通过实际示例&#xff0c;展示如何在Python中使用代理IP进行网络爬虫。 1. 环境准备 首先&#xff0c;确保您已安装Python和所需的库。在本示…...

样式,常用组件

3、代码实现登录的思路 设置属性的成员方法都有统一的命名规范&#xff1a; set&#xff08;&#xff09;//就是某种属性的名字 父窗口&#xff1a;组件嵌套到那个主窗口中&#xff0c;这个主窗口就是父窗口 第一步&#xff1a;创建一个标签对象用来显示登录界面的标题 QLabe…...

Django Project | 云笔记练习项目

文章目录 功能整体架构流程搭建平台环境子功能先创建用户表 并同步到数据库1.用户注册密码存储 -- 哈希算法唯一索引引发的重复问题 try登陆状态保持 -- 详细看用户登录状态 2. 用户登录会话状态时间 cookie用户登录状态校验 3. 网站首页4.退出登录5.笔记模块 列表页添加笔记 …...

Zookeeper的监听机制

Zookeeper的监听机制是Zookeeper框架中一个至关重要的功能&#xff0c;它实现了分布式系统中数据状态变化的实时通知&#xff0c;使得客户端能够及时响应并处理这些变化。下面将详细解析Zookeeper的监听机制及其原理&#xff0c;包括监听器的注册、事件通知的处理、监听器的特点…...

Swift withAnimation 动画完成监听

在ios17中withAnimation有completion方法可以监听动画完成&#xff0c;但是低于ios17没有&#xff0c;需要自定义一个监听器&#xff0c;原理就是通过AnimatableModifier可以监听到值的didSet修改&#xff0c;我们就可以调用回调函数。 代码 // 动画完成监听 struct Animatabl…...

场外期权交易:找到适合你的那一款

各位期权爱好者们&#xff01;今天咱们来聊聊在进行场外期权交易时&#xff0c;怎么去评估和选择适合自己风险承受能力的期权产品。 第一&#xff0c;你得对自己有个清楚的认识。想想看&#xff0c;你是那种激进型的冒险家&#xff0c;还是保守型的稳健派呢&#xff1f;了解自己…...

Elasticsearch-使用java 批量插入文档

首先创建两个实体类&#xff0c;用于存放所需值 开始编写接口&#xff0c;这里我使用的是RestController风格&#xff0c;然后使用PostMapping注解&#xff0c;入参根据自己的需求自定义&#xff0c;没有固定规范 这里实现接口的方法 然后重写接口中的方法&#xff08;编写核心…...

【区块链+食品安全】农业产业全过程溯源云平台 | FISCO BCOS应用案例

近年来&#xff0c;食品安全问题频发&#xff0c;尤其疫情期间&#xff0c;海鲜、冷冻畜牧产品的入口安全成为大众关注焦点&#xff0c;追溯、确保相关产品生产、运输、售卖等环节的信息真实、有效&#xff0c;成为保证食品安全的核心环节。浙江天演维真网络科技股份有限公司基…...

每日面试题Day2

C语言中 # 和 ## 的用法 # 是 字符串化操作符,定义时用括号代表参数传递, 可以把传入的参数名替换成带双引号的字符串 定义: #define a(b) #a 使用:a(123) 编译时会展开成 "123" ## 是字符串连接符,定义时用括号代表参数传递, 可以把参数在宏定义的字符…...

基于MyBatis-plus的SpringBoot开发

目录 一、SpringBoot整合mybatis 二、SpringBoot整合mybatis-plus 1、什么是mybatis-plus&#xff1f; 2、mybatis-plus的特性 3、mybatis-plus的使用 &#xff08;1&#xff09;编写注解配置实体类与关系表映射关系 &#xff08;2&#xff09;mapper层 &#xff08;3…...

网站数据导出为excel 源码大全java php c# js python 与网络安全兼顾-阿雪技术观

一、阿雪技术观谈网站安全 1.保护用户隐私和数据 用户在访问网站时会提供各种个人信息&#xff0c;如姓名、地址、联系方式、信息等。如果网站存在安全漏洞&#xff0c;这些敏感信息可能会被黑客窃取&#xff0c;导致用户遭受身份盗窃、欺诈等 2.维护企业声誉和信任 一个安全可…...

Python知识点21---怎么把你的Python项目打包成一个完整的结果物给别人提供

很多写Python的人&#xff0c;都会遇到一个很抓瞎的事情&#xff0c;项目这么打包&#xff1f;就比如写Java代码写惯了&#xff0c;突然写个Python&#xff0c;就在想怎么办Python的平替Maven是什么&#xff1f;怎么把环境和写的代码打成一个结果物&#xff1f;这篇就告诉你。 …...

关于#genesiscsheel#的问题,如何解决?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…...

无人机之如何避免飞行错误篇

在无人机飞行中&#xff0c;飞手可能会遇到各种问题&#xff0c;这些问题不仅会影响飞行效果&#xff0c;还可以带来安全隐患。以下是一些常见的错误及避免方法&#xff0c;帮助飞手提高飞行稳定性和安全性&#xff1a; 一、校准传感器 IMU&#xff08;惯性测量单位&#xff0…...

做网站是不是要学编程/免费大数据网站

1、安装EPEL和Remi存储库 如果要安装PHP7&#xff0c;首先需要在Centos7系统上安装并启用EPEL和Remi存储库 yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpmyum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm 2、安装…...

制作网站开发/电脑培训班零基础网课

知名企业家、同时也是 NBA 小牛队的老板马克库班&#xff08;Mark Cuban&#xff09;曾说过一句话&#xff1a;人工智能&#xff0c;深度学习和机器学习&#xff0c;不论你现在是否能够理解这些概念&#xff0c;你都应该学习。否则三年内&#xff0c;你就会像灭绝的恐龙一样被社…...

wordpress 中国版/设计案例网

在Excel统计数据时&#xff0c;经常会碰到重复项反复出现&#xff0c;很干扰视线&#xff0c;想要对重复项进行合并并求和&#xff0c;那要如何操作呢&#xff1f;下面&#xff0c;小编跟大家详细讲解Excel合并重复项数据并求和的操作方法。首先打开一个需要处理的Excel表格&am…...

自定义优定软件网站建设/网站搭建公司

脚本范例分析&#xff1a;先来看看一段用INNO SETUP脚本向导创建的基本脚本的[Setup]段&#xff1a; [Setup]AppNamePremiere 6.5 汉化补丁-----------------(程序名称)AppVerNamePremiere 6.5 汉化补丁------------(程序名称版本)AppPublisher浩子工作室---------------------…...

paypal可做网站/5188关键词平台

前一阵子团队组织了敏捷和TDD的培训&#xff0c;这里记录一下。 1.敏捷开发 1&#xff09;敏捷宣言 我们一直在实践中探寻更好的软件开发方法&#xff0c;身体力行的同时也帮助他人&#xff0c;由此我们建立了如下价值观&#xff1a;个体和互动 高于 流程和工具 工作的软件 …...

恒锐奇 做网站/百度推广网站一年多少钱

可以在组件中的script标签中定义methods:{}&#xff0c;在methods中定义函数&#xff0c;并通过v-on:click绑定该函数为点击事件&#xff0c;在对象被点击时就会自动触发执行该js函数&#xff0c;达到动态效果。 示例&#xff1a;v-on:click"xxx"可用click"xxx&…...