C++ 內存管理(內存分布 , 管理方式 , new和delete實現原理)

目錄

1. C/C++內存分布

練習:

2. C語言動態內存管理方式

2.1?malloc/calloc/realloc的區別

2.2 malloc的實現原理

2.3 內存塊分布與擴容

3. C++動態內存管理方式

3.1 new/delete操作類內置類型

1. new操作內置類型

2. delete操作內置類型

3.2?new/delete操作類自定義類型

1. new操作自定義類型

2.?delete操作自定義類型

4.?operator new與operator delete函數

4.1 operator new??函數

4.2?operator delete函數

4.3 與new/delete操作符的關系

5. new和delete的實現原理

5.1 內置類型

5.2 自定義類型

6.?new/delete?和 malloc/free的區別

1. 所屬語言

2. 操作對象與功能

3. 數組操作

4. 內存不足處理

5. 重載與自定義

7. 總結:


1. C/C++內存分布

在C和C++中 , 程序的內存分布通常可劃分為幾個主要區域 , 這些區域各自承擔不同的功能 , 具體如下:

1. 棧(Stack)

  • 特點 : 由編譯器自動管理 , 空間較小(通常幾MB) , 遵循“先進后出”原則。
  • 存儲內容 : 函數的局部變量 , 函數參數 , 返回地址等。
  • 示例 : 函數內部定義的?int a = 10;,a就存儲在棧中 , 函數執行結束后會自動釋放。

2. 堆(Heap)

  • 特點 : 由程序員手動管理(C中用?malloc?/?free , C++中用?new?/?delete) , 空間較大(可達GB級別) , 分配和釋放需要顯式操作。
  • 存儲內容 : 動態分配的內存 , 比如動態創建的對象、數組等。
  • 示例 : int* p = new int[10]; , 數組的內存就位于堆中 , 需用?delete[] p?手動釋放 , 否則可能導致內存泄漏。

3. 全局/靜態存儲區(Global/Static Storage Area)(數據段)

  • 特點 : 程序運行期間一直存在 , 由編譯器管理 , 程序結束后自動釋放。
  • 存儲內容:
  • 全局變量(定義在函數外的變量);
  • 靜態變量(用?static?修飾的變量 , 包括全局靜態變量和局部靜態變量)。
  • 示例 : int g_var = 20;(全局變量) , static int s_var = 30;(靜態變量) , 都存儲在此區域。

4. 常量存儲區(Constant Storage Area)(代碼段)

  • 特點 : 存放常量 , 內容不可修改 , 程序結束后釋放。
  • 存儲內容 : 字符串常量(如"hello") , const?修飾的常量(全局或靜態的?const?變量 , 局部const?變量可能在棧中)。
  • 示例 : const int c_var = 40;(全局常量) , char* str = "world";("world"?存于常量區)。

5. 代碼區(Code Segment/Text Segment)

  • 特點 : 存放程序的機器指令(二進制代碼) , 通常為只讀 , 以防止意外修改。
  • 作用 : CPU從這里讀取指令并執行程序。

總結來說 , 棧和堆用于動態管理運行時數據 , 全局/靜態區和常量區存儲生命周期較長的數據 , 代碼區則負責存儲程序的執行指令 , 這些區域共同構成了C和C++程序的內存布局。

練習:

?以下是對每個變量內存位置的詳細分析:

  1. globalVar :?屬于全局變量 , 存儲在數據段(靜態區 , 選項C)。全局變量在程序整個運行周期都存在 , 由編譯器管理其內存 , 程序結束時自動釋放。
  2. staticGlobalVar : 是全局靜態變量,同樣存儲在數據段(靜態區 ,?選項C)。靜態全局變量作用域限制在定義的文件內 , 但存儲區域和全局變量一樣 , 在數據段 , 生命周期貫穿程序運行。
  3. staticVar : 為函數內的靜態變量 , 存儲在數據段(靜態區 ,?選項C)。函數內的靜態變量 , 在第一次函數調用時初始化 , 之后一直存在于數據段 , 直到程序結束。
  4. localVar :?是函數內的局部變量 , 存儲在棧(選項A)。局部變量在函數調用時在棧上分配空間 , 函數執行完畢 , 棧空間自動釋放。
  5. num1 :?是函數內的局部數組 , 存儲在棧(選項A)。局部數組屬于局部變量 , 在棧上分配內存 , 函數結束后棧空間回收。
  6. char2 :?char2?是函數內的字符數組 , 存儲在棧(選項A);而?"abcd"?作為字符串常量 , 存儲在代碼段(常量區 ,?選項D) , 數組?char2?是在棧上 , 將常量區的字符串內容拷貝過來。
  7. *char2 :?char2?是棧上的數組 , *char2?是數組的第一個字符 , 所以存儲在棧(選項A)。
  8. pChar3 :?pChar3?是指針變量 , 存儲在棧(選項A) , 它指向的是字符串常量?"abcd"
  9. *pChar3 :?pChar3?指向的字符串常量?"abcd"?存儲在代碼段(常量區 ,?選項D) , 所以*pChar3(即字符串的字符)在代碼段(常量區?, 選項D)。
  10. ptr1 : ptr1?是指針變量 , 存儲在棧(選項A) , 它指向堆上的內存。
  11. *ptr1 : ptr1?通過?malloc?動態分配的內存位于堆(選項B) , 所以*ptr1(即所指向的內存區域)在堆(選項B)。

2. C語言動態內存管理方式

2.1?malloc/calloc/realloc的區別

在前面的C語言中 , 我們學習了C語言的動態動態內存管理方式 , 其中主要學了在malloc , calloc , realloc?和free等函數 , 下面我們再簡單回顧一下它們之間的區別:

在C語言中 , malloc , calloc , realloc?和free是實現動態內存管理的重要函數 , 它們各自有不同的功能和使用方式:
1. malloc函數

  • 函數原型:void* malloc(size_t size);?
  • 功能:在堆內存中分配指定字節數的連續內存空間。函數返回一個指向分配內存起始地址的指針 , 如果分配失敗(例如內存不足) , 則返回NULL?。
  • 注意事項:
  • malloc?分配的內存空間中的值是未初始化的 , 可能是任意值。
  • 使用完 malloc?分配的內存后 , 必須調用 free?函數釋放 , 否則會導致內存泄漏。
  • 由于?malloc?返回的是 void*?類型指針 , 在賦值給其他類型指針時 , 需要進行強制類型轉換。

2. calloc函數

  • - 函數原型:void* calloc(size_t num, size_t size);?
  • - 功能 : 在堆內存中分配 num?個大小為 size?字節的連續內存空間 , 并將這些空間初始化為0。它返回一個指向分配內存起始地址的指針 , 如果分配失敗 , 則返回?NULL?。
  • 注意事項:
  • 相比 malloc , calloc會自動進行初始化操作 , 適合需要初始值為0的場景?, 不過也因為多了初始化操作 , 在性能上會有一定開銷。
  • 同樣 , 使用完后要調用 free?釋放內存。

3. realloc函數

  • 函數原型:? void* realloc(void* ptr, size_t size);?
  • 功能:用于重新分配已分配的內存空間。ptr?是指向之前由 malloc , calloc?或 realloc?分配的內存塊的指針 , size?是新的內存塊大小。如果?ptr?為 NULL?, 則?realloc?相當于malloc;如果?size?為0且?ptr?不為NULL , 則釋放 ptr?指向的內存塊 , 相當于 ?free(ptr)?。
  • 注意事項:
  • realloc?可能會移動原來內存塊的位置 , 因為它要根據當前內存的使用情況和新的大小來決定是否重新分配一塊新的連續內存空間。所以在調用 realloc?后 , 要使用其返回的新指針 , 而不能再使用原來的指針。
  • 如果重新分配失敗 , 原來 ptr?指向的內存塊不會被釋放 , 仍然有效。

4. free函數

  • 函數原型:void free(void* ptr);?
  • 功能:釋放由 malloc , calloc?或 realloc?分配的內存空間 , 讓系統可以回收并重新利用這部分內存。ptr?是指向要釋放的內存塊的指針。
  • 使用示例:在前面介紹?malloc , calloc , realloc?的示例中都有使用free釋放內存的操作。
  • 注意事項:
  • 只能釋放由 malloc , calloc , realloc?分配的內存 , 釋放其他內存會導致未定義行為。
  • 不能多次釋放同一塊內存 , 也不能釋放 NULL?指針(雖然釋放?NULL?指針不會報錯 , 但也無實際意義)。
#include <stdio.h>
#include <stdlib.h> // 包含動態內存管理函數的頭文件int main() {int *ptr1, *ptr2, *ptr3;// 1. 使用 malloc 分配內存(未初始化)ptr1 = (int*)malloc(3 * sizeof(int)); // 分配3個int的空間// 2. 使用 calloc 分配內存(自動初始化為0)ptr2 = (int*)calloc(4, sizeof(int)); // 分配4個int的空間// 3. 使用 realloc 調整已分配的內存(基于ptr1擴展)ptr3 = (int*)realloc(ptr1, 5 * sizeof(int)); // 將ptr1的3個int擴展為5個// 4. 釋放所有動態分配的內存free(ptr3); // 釋放realloc返回的新地址(原ptr1已被覆蓋,無需重復釋放)free(ptr2); // 釋放calloc分配的內存return 0;
}

2.2 malloc的實現原理

malloc?是C語言中用于動態分配內存的函數 , 其工作原理可簡要概括為:

  1. 內存池管理:程序運行時會有一塊預設的堆內存區域(內存池) , malloc?負責管理這塊區域 , 而非直接向操作系統申請內存。
  2. 分配過程:當調用 malloc?申請指定大小的內存時 , 它會在內存池中查找足夠大的空閑內存塊 , 劃分出所需大小的部分 , 返回指向該部分的指針 , 并記錄該內存塊的使用信息(如大小、狀態)。
  3. 內存池擴容:若內存池中沒有足夠的空閑內存 , malloc?會通過系統調用(如 Linux 中的 ?brk?或 mmap)向操作系統申請更多內存 , 擴充內存池后再進行分配。
  4. 配合釋放操作:當通過 free?釋放內存時 , malloc?會根據之前記錄的信息回收內存塊 , 標記為空閑 , 并可能合并相鄰的空閑塊 , 以減少內存碎片 , 提高后續分配效率。

2.3 內存塊分布與擴容

動態內存分配中:

  1. 內存塊分布:已分配的內存塊和空閑塊在堆區混雜存在。當申請新內存時 , 若有合適大小的空閑塊 , 直接分配;
  2. 擴容:若要給已分配的內存塊擴容(如用?realloc ) ,? 如果原內存塊后有足夠空閑空間 , 直接原地擴大;若沒有 , 就新找一塊足夠大的連續空間 , 復制原數據后釋放舊空間 , 返回新地址。

3. C++動態內存管理方式

C語言的動態內存管理方式在C++中仍然可以繼續使用 , 但是有些地方就會顯得無能為力了 , 而且使用起來比較麻煩 , 因此C++又提出了一種屬于自己的動態內存管理方式 , 通過new和delete操作符進行動態內存管理。

3.1 new/delete操作類內置類型

在 C++ 中 , new?和?delete?操作內置類型(如 int , double , char??等)時 , 流程相對簡單 , 不涉及對象的構造和析構(因為內置類型沒有構造函數和析構函數) , 核心是內存的分配與釋放:

1. new操作內置類型

分配單個元素:如?int* p = new int;?

  • 步驟 : 向堆區申請一塊能容納?int?類型的內存空間 , 返回指向該空間的指針。
  • 注意 : 默認不初始化 , 內存中的值是隨機的;若要初始化 , 可寫成?int* p = new int(10); , 此時內存會被初始化為10。

分配數組:如 int* arr = new int[5];?

  • 步驟 : 向堆區申請能容納5個?int?的連續內存空間 , 返回指向首元素的指針。
  • 注意 : 默認不初始化;若要初始化所有元素為 0 , 可寫成?int* arr = new int[5]();?。

2. delete操作內置類型

釋放單個元素:如?delete p;?

  • 步驟:直接釋放?p?指向的堆內存(無需額外清理 , 因無析構函數) , p?變為野指針(建議置為 nullptr)。

釋放數組:如 ?delete[] arr;?

  • 步驟:釋放?arr?指向的整個連續數組內存 , 必須用 delete[]??匹配 new[] (雖然內置類型下用 delete?可能不報錯 , 但會導致行為未定義 , 是錯誤寫法)。

簡言之 , 內置類型的?new?/?delete?核心是“分配/釋放堆內存” , 比自定義類型少了構造/析構步驟 , 但仍需嚴格匹配?new?與 delete , new[]?與?delete[]。

3.2?new/delete操作類自定義類型

new?和 delete?操作自定義類型時 , 會完整包含“內存管理”和“對象生命周期管理”兩個環節 , 具體流程如下:

1. new操作自定義類型

以類?A?為例分配單個對象:如 A* p = new A;?

  • 1.?先調用底層內存分配函數(類似?malloc) , 在堆區申請一塊能容納 A?類型對象的內存。
  • 2.?自動調用 A?的構造函數(根據參數匹配對應構造函數 , 如無參數則調用默認構造函數) , 初始化這塊內存中的對象(例如初始化成員變量 , 申請資源等)。
  • 3.?返回指向該對象的指針?p。

分配數組:如?A* arr = new A[3];?

  • 1.?申請能容納3個?A?對象的連續堆內存。
  • 2.?依次調用3次?A?的構造函數(每個元素對應一次) , 初始化數組中的每個對象。

2.?delete操作自定義類型

釋放單個對象:如 delete p;?

  • 1.?先調用 p?指向對象的析構函數(?A::~A() ) , 清理對象內部資源(例如釋放成員變量指向的堆內存 , 關閉文件等)。
  • 2.?調用底層內存釋放函數(類似?free ) , 將對象占用的堆內存歸還給系統
  • 3.?指針?p?變為野指針 , 建議置為 nullptr

釋放數組:如 delete[] arr;?

  • 1.?先按相反順序依次調用數組中每個A對象的析構函數(共 3 次) ,?清理所有元素的資源。
  • 2.?釋放整塊連續內存。
  • 注意 : 必須用 delete[]?匹配 new[] , 否則會導致部分對象析構函數不被調用 , 造成資源泄漏。

核心區別:自定義類型的 new?/?delete?比內置類型多了構造函數初始化對象和析構函數清理資源的步驟 , 這是C++面向對象特性在內存管理中的直接體現 , 確保對象從創建到銷毀的完整生命周期管理。

//new和delete操作自定義類型
#include<iostream>
using namespace std;class A
{
public:A(int a = 0) //構造函數: _a(a){cout << "A():" << this << endl;}~A() //析構函數{cout << "~A():" << this << endl;}
private:int _a;
};int main()
{// new/delete 和 malloc/free最大區別是 new/delete對于【自定義類型】除了開空間還會調用構造函數和析構函數//自定義類型A* p1 = (A*)malloc(sizeof(A));free(p1);A* p2 = new A(1);delete p2;//內置類型是幾乎是一樣的int* p3 = (int*)malloc(sizeof(int)); free(p3);int* p4 = new int;delete p4;A* p5 = (A*)malloc(sizeof(A) * 10);free(p5);A* p6 = new A[10];delete[] p6;return 0;
}

輸出結果:

4.?operator new與operator delete函數

new和delete是用戶進行動態內存申請和釋放的操作符 , operator new 和operator delete是系統提供的全局函數 , new在底層調用operator new全局函數來申請空間 , delete在底層通過operator delete全局函數來釋放空間。可以理解為operator new?和 operator delete?是 new?和?delete?操作符的底層支撐 , 主要負責內存的分配與釋放(不涉及對象的構造和析構):

4.1 operator new??函數

  • 功能:負責在堆上分配指定大小的內存塊 , 與 C 語言中的?malloc?類似 , 但行為有差異(operator new?分配失敗時默認拋出 std::bad_alloc?異常 , 而?malloc 則會返回 NULL)。
  • 函數原型(簡化版) : void* operator new(size_t size); 其中 size?是要分配的內存字節數。
  • 使用示例:
#include <iostream>
#include <new> ?// 包含相關異常定義等int main() 
{// 分配能容納一個 int 類型的內存int* p = (int*)operator new(sizeof(int));if (p == nullptr) {std::cout << "內存分配失敗" << std::endl;return 1;}*p = 10;std::cout << *p << std::endl;operator delete(p);return 0;
}
  • 特點:
  • 只分配內存 , 不調用對象的構造函數(這是和 new?操作符的關鍵區別 , new?會在 operator new?分配內存后調用構造函數)。
  • 可以被重載 , 用戶能自定義內存分配的方式(比如使用內存池等)。

4.2?operator delete函數

  • 功能 : 負責釋放由?operator new?分配的內存塊 , 與 C 語言中的?free?類似。
  • 函數原型(簡化版) : void operator delete(void* ptr); 其中 ptr?是要釋放的內存塊指針。
  • 使用示例 : 如上面的示例 , 在使用 operator new?分配內存后 , 通過 operator delete(p)?釋放內存。
  • 特點:
  • 只釋放內存 , 不調用對象的析構函數(這是和 delete?操作符的關鍵區別 , delete?會在調用 operator delete?釋放內存前調用析構函數)。
  • 同樣可以被重載 , 用戶能自定義內存釋放的邏輯。

4.3 與new/delete操作符的關系

  • new?操作符的執行過程 : 先調用 operator new?分配內存 , 然后調用對象的構造函數初始化對象。
  • delete?操作符的執行過程 : 先調用對象的析構函數清理對象 , 然后調用?operator delete?釋放內存。
  • 簡單來說 , operator new?和 operator delete?是更底層的內存分配/釋放工具 , new?和?delete?則是在它們的基礎上 , 結合了對象的構造和析構操作 , 更符合 C++ 面向對象的特性。

5. new和delete的實現原理

5.1 內置類型

  • 如果申請的是內置類型的空間 , new和malloc , delete和free基本類似 , 不同的地方是:new/delete申請和釋放的是單個元素的空間 , new[]和delete[]申請的是連續空間 , 而且new在申請空間失敗時會拋異常 , malloc會返回NULL。

5.2 自定義類型

new的原理

  • 1. 調用operator new函數申請空間
  • 2. 在申請的空間上執行構造函數 , 完成對象的構造

delete的原理

  • 1. 在空間上執行析構函數 , 完成對象中資源的清理工作
  • 2. 調用operator delete函數釋放對象的空間

new T[N]的原理

  • 1. 調用operator new[]函數 , 在operator new[]中實際調用operator new函數完成N個對象空間的申請
  • 2. 在申請的空間上執行N次構造函數

delete[]的原理

  • 1. 在釋放的對象空間上執行N次析構函數 , 完成N個對象中資源的清理
  • 2. 調用operator delete[]釋放空間 , 實際在operator delete[]中調用operator delete來釋放空間

6.?new/delete?和 malloc/free的區別

new/delete?和 malloc/free 都是 C++(及C)中用于動態內存管理的工具 , 主要區別如下:

1. 所屬語言

  • malloc?/?free?是 C 語言的標準庫函數 , 在 C++ 中也可使用 , 但更偏向于底層內存操作。
  • new?/?delete?是 C++ 的操作符 , 是 C++ 面向對象特性在內存管理上的體現。

2. 操作對象與功能

  • malloc?/?free?:
  1. 僅負責內存的分配與釋放 , 不涉及對象的構造和析構(因為C是面向過程語言 , 無“對象”概念)。
  2. malloc?需手動計算內存大小(如?malloc(sizeof(int)) ) , 返回?void* , 使用時通常需要強制類型轉換。
  3. free?只需傳入要釋放的內存指針。
  • new?/?delete?:
  1. 不僅分配/釋放內存 , 還會自動調用對象的構造函數(?new?時)和析構函數(?delete?時)(針對自定義類型)。
  2. new?無需手動計算類型大小(如?new int?會自動分配 int?大小的內存) , 直接返回對應類型的指針 , 無需強制類型轉換。
  3. delete?只需傳入對象指針。

3. 數組操作

  • malloc?/?free?:
  1. 分配數組需手動計算總內存大小(如 ?malloc(5 * sizeof(int)) ) , 釋放時直接 free?指針 , 不涉及數組元素的“逐個清理”(因為無析構函數)。
  • new?/?delete?:
  1. 分配數組用 ?new[] (如?new int[5] ) , 會為數組中每個元素(若為自定義類型)調用構造函數;釋放數組用?delete[] , 會為每個元素調用析構函數 , 然后釋放整塊內存。若用 delete?釋放?new[]?分配的數組(自定義類型) , 會因析構函數調用不完整導致內存泄漏或錯誤。

4. 內存不足處理

  • malloc : 內存不足時返回 NULL , 需手動檢查返回值。
  • new : 內存不足時默認拋出 std::bad_alloc?異常 , 可通過異常處理機制捕獲 , 也可自定義 new?的行為(如設置內存不足的回調)。

5. 重載與自定義

  • malloc?/?free : 不可重載 , 行為固定。
  • new?/?delete : 可以重載 , 用戶可自定義內存分配和釋放的邏輯(比如使用內存池等) , 更靈活地滿足特定需求。

簡單來說 , new?/?delete?是更“面向對象”的內存管理方式 , 封裝了對象構造/析構的邏輯;而 malloc?/?free?更底層 , 僅關注內存塊的分配與釋放。在 C++ 中 , 更推薦使用 new?/?delete (尤其是處理自定義類型時) , 以利用其對對象生命周期的管理能力。

7. 總結:

本文系統介紹了C/C++程序的內存分布與動態內存管理機制。內存主要分為棧、堆、全局/靜態區、常量區和代碼區五部分 , 各自承擔不同功能。C語言通過malloc/calloc/realloc/free進行動態內存管理 , 而C++引入了更高級的new/delete操作符 , 不僅能分配內存還能自動調用構造/析構函數。文章詳細對比了malloc/free與new/delete的區別 , 并深入解析了operator new/delete的實現原理。關鍵在于:C++的new/delete是面向對象的內存管理方式 , 而malloc/free只進行原始內存操作。在C++開發中 , 特別是處理自定義類型時 , 應優先使用new/delete以確保完整的對象生命周期管理。

最后 , 感謝大家的觀看!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/93350.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93350.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93350.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

1.2. qemu命令起虛擬機增加網絡配置

1. 網絡配置 常見的網絡模式分為tap網絡和基礎網絡模式兩種。 1.1. TAP網絡&#xff08;橋接模式&#xff09; 虛擬機直接接入宿主機物理網絡&#xff0c;獲得獨立IP 1.1.1. 使用tap方式起虛擬機網絡-netdev tap,idhostnet0,ifnametap0 \-device virtio-net-pci,netdevhostnet0…

分享一個Oracle表空間自動擴容與清理腳本

一、基礎環境準備&#xff08;首次執行&#xff09; -- 1. 創建表空間監控表&#xff08;存儲使用率、容量等信息&#xff09; create table monitor_tablespace_rate (tbs_name varchar2(50), -- 表空間名total_gb number, -- 總容量(GB)used_gb number, …

Flink Sql 按分鐘或日期統計數據量

一、環境版本 環境版本Flink1.17.0Kafka2.12MySQL5.7.33 【注意】Flink 1.13版本增加Cumulate Window&#xff0c;之前版本Flink Sql 沒有 Trigger 功能&#xff0c;長時間的窗口不能在中途觸發計算&#xff0c;輸出中間結果。比如每 10S 更新一次截止到當前的pv、uv。只能用T…

LeetCode 2460.對數組執行操作

給你一個下標從 0 開始的數組 nums &#xff0c;數組大小為 n &#xff0c;且由 非負 整數組成。 你需要對數組執行 n - 1 步操作&#xff0c;其中第 i 步操作&#xff08;從 0 開始計數&#xff09;要求對 nums 中第 i 個元素執行下述指令&#xff1a; 如果 nums[i] nums[i …

深入解析 @nestjs/typeorm的 forRoot 與 forFeature

nestjs/typeorm 是 NestJS 與 TypeORM 集成的官方模塊&#xff0c;提供了 forRoot() 和 forFeature() 兩個核心靜態方法用于配置數據庫連接和實體注冊。本文將深入解析這兩個方法的機制、使用場景和最佳實踐。 一、TypeOrmModule.forRoot() - 全局數據庫配置 forRoot() 方法用于…

關于simplifyweibo_4_moods數據集的分類問題

本來打算用情感分類數據集拿Transformer模型來練練手&#xff0c;發現訓練效果并不好。當我分析了這個數據集的標簽后發現問題了&#xff1a; 查看標簽的分布&#xff1a; import pandas as pd# 先直接讀取數據&#xff0c;不進行后續處理 data_file ~/data/simplifyweibo_4_m…

Custom SRP - Baked Light

https://catlikecoding.com/unity/tutorials/custom-srp/baked-light/本篇教程介紹將靜態光照烘焙到 light map 和 light prob 中.首先貼上我遇到的問題,希望遇到的同學幫忙解答:實踐本教程過程中,定義的 MetaPass 沒有效果, Unity 始終在使用默認的 meta pass,我使用的是 unit…

[Python]PTA:實驗2-3-1-for 求1到100的和

本題要求編寫程序&#xff0c;計算表達式 1 2 3 ... 100 的值。輸入格式&#xff1a;本題無輸入。輸出格式&#xff1a;按照以下格式輸出&#xff1a;sum 累加和代碼如下&#xff1a;x0 for i in range(1,101,1):xi print("sum {}".format(x))

【解決筆記】MyBatis-Plus 中無 selectList 方法

MyBatis-Plus 中無 selectList 方法的解決筆記 核心前提 MyBatis-Plus 的 BaseMapper 接口內置了 selectList 等基礎查詢方法&#xff0c;繼承該接口可直接使用&#xff0c;無需手動實現。 無 selectList 方法的兩種情況及解決方式 1. 未繼承 BaseMapper&#xff08;推薦方案&a…

一周學會Matplotlib3 Python 數據可視化-繪制箱線圖(Box)

鋒哥原創的Matplotlib3 Python數據可視化視頻教程&#xff1a; 2026版 Matplotlib3 Python 數據可視化 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 課程介紹 本課程講解利用python進行數據可視化 科研繪圖-Matplotlib&#xff0c;學習Matplotlib圖形參數基本設置&…

4.4 vue3生命周期函數

vue3生命周期函數生命周期鉤子名稱對比表階段Vue 2 選項式 APIVue 3 組合式 API說明創建前beforeCreateonBeforeCreate&#xff08;已廢棄&#xff09;Vue 3 中 setup() 替代創建完成createdsetup()&#xff08;替代&#xff09;setup 是入口&#xff0c;代替 beforeCreate 和 …

無腦整合springboot2.7+nacos2.2.3+dubbo3.2.9實現遠程調用及配置中心

簡介&#xff1a; 好久沒有寫博客了&#xff0c;最近辭職了有時間進行一次分享&#xff0c;今天我們主要是使用單體服務springboot整合nacos實現配置中心&#xff0c;然后整合dubbo來實現遠程的rpc調用。如下是本地案例架構圖&#xff0c;生產者和消費者的配置在nacos配置中心上…

騰訊位置商業授權微信小程序逆地址解析(坐標位置描述)

微信小程序JavaScript SDK 開發指南 逆地址解析(坐標位置描述) reverseGeocoder(options:Object) 本接口提供由坐標到坐標所在位置的文字描述的轉換&#xff0c;輸入坐標返回地理位置信息和附近poi列表。 注&#xff1a;坐標系采用gcj02坐標系 options屬性說明 屬性類型必填…

3D商品展示:技術狂歡下的普及困局

當微軟推出Copilot 3D——僅需一張照片即可生成可編輯的3D模型時&#xff0c;業界曾歡呼“建模門檻徹底消失”。然而技術的美好愿景卻撞上現實的銅墻鐵壁&#xff1a;當前電商平臺3D商品加載卡頓導致用戶跳出率超60%&#xff0c;企業3D化滲透率仍不足34%。絢爛的技術煙花下&…

(Arxiv-2025)Stand-In:一種輕量化、即插即用的身份控制方法用于視頻生成

Stand-In&#xff1a;一種輕量化、即插即用的身份控制方法用于視頻生成 paper是WeChat發布在Arxiv 2025的工作 paper title:Stand-In: A Lightweight and Plug-and-Play Identity Control for Video Generation Code&#xff1a;鏈接 圖1&#xff1a;給定一張參考圖像&#xff…

數據科學與爬蟲技術學習筆記

數據科學與爬蟲技術學習筆記 一、數據科學基礎庫 1. NumPy&#xff1a;數值計算的基石 NumPy 是 Python 科學計算的核心庫&#xff0c;專為數組和矩陣操作設計&#xff0c;能大幅簡化循環操作&#xff0c;提供豐富的數學函數。 核心優勢&#xff1a;高效處理同類型元素的多維…

學習嵌入式之硬件——I2C

一、I2C1.定義內部集成電路的簡稱&#xff0c;半雙工串行同步通信&#xff0c;是芯片和芯片之間的通信方式&#xff1b;通常只有一個主機&#xff0c;多個從機&#xff0c;采用主從應答的方式上圖所示是IIC的總線的使用場景&#xff0c;所有掛載在IIC總線上的設備都有兩根信號線…

使用websockt

封裝websocktHooksimport { ref, onMounted, onUnmounted } from vue;/*** webSocket的Hooks* param {string} websocket鏈接地址* */ export function useWebSocket(url: string) {// 核心狀態 const data: Ref<any> ref(null);//收到websocket返回的數據const socke…

Jmeter自定義腳本

目錄 log&#xff1a;輸出類 Label&#xff1a;你自定義的組件的名稱 FileName&#xff1a;添加的腳本文件的文件名 Parameters&#xff1a;你傳入的參數&#xff0c;是一個字符串 args&#xff1a;你傳入的參數&#xff0c;是一個數組 Parameters和args的異同&#xff1…

飛算 JavaAI 電商零售場景實踐:從訂單峰值到供應鏈協同的全鏈路技術革新

目錄 一、電商核心場景的技術攻堅 1.1 分布式訂單系統的事務一致性設計 1.1.1 TCC 模式下的訂單創建流程 1.1.2 訂單狀態機的可靠流轉 1.2 高并發秒殺系統的架構設計 1.2.1 多級限流與流量削峰 1.2.2 庫存防超賣機制 1.3 智能推薦與用戶行為分析 1.3.1 用戶行為實時采…