C++動(dòng)態(tài)數(shù)組兩種實(shí)現(xiàn)方式詳解(std::vector vs malloc)
在C++中,動(dòng)態(tài)數(shù)組是處理可變大小數(shù)據(jù)集合的常見(jiàn)需求。本文將詳細(xì)介紹兩種主要的實(shí)現(xiàn)方式:使用C++標(biāo)準(zhǔn)庫(kù)的std::vector和使用C風(fēng)格的malloc,并對(duì)比它們的差異、使用方法以及最佳實(shí)踐。
1. std::vector:現(xiàn)代C++的推薦方式
1.1 基本語(yǔ)法與參數(shù)
// 基本語(yǔ)法 std::vector<T> name(size); // 實(shí)際示例 std::vector<uint8_t> occlusions(points_cnt);
參數(shù)詳解:
- 模板參數(shù)
T:指定向量中元素的類型,這里是uint8_t(無(wú)符號(hào)8位整數(shù),通常就是unsigned char) - 構(gòu)造函數(shù)參數(shù)
size:指定向量初始的大小,這里是points_cnt(必須是整數(shù)類型) - 向量名稱
occlusions:變量名,遵循C++命名規(guī)則
1.2 如何訪問(wèn)和操作元素
訪問(wèn)單個(gè)元素:
// 使用下標(biāo)運(yùn)算符(不進(jìn)行邊界檢查) occlusions[0] = 255; // 設(shè)置第一個(gè)元素 uint8_t value = occlusions[0]; // 獲取第一個(gè)元素 // 使用at()方法(進(jìn)行邊界檢查,安全但稍慢) occlusions.at(0) = 255; // 如果索引越界會(huì)拋出std::out_of_range異常 uint8_t value = occlusions.at(0); // 使用迭代器 auto it = occlusions.begin(); // 獲取起始迭代器 *it = 255; // 通過(guò)迭代器訪問(wèn)元素
遍歷所有元素:
// 方法1:使用下標(biāo)循環(huán)
for (size_t i = 0; i < occlusions.size(); ++i) {
occlusions[i] = i % 256; // 賦值
std::cout << (int)occlusions[i] << " "; // 訪問(wèn)
}
// 方法2:使用范圍for循環(huán)(C++11起)
for (uint8_t& val : occlusions) {
val = 128; // 可以直接修改
}
// 方法3:使用迭代器
for (auto it = occlusions.begin(); it != occlusions.end(); ++it) {
*it = 64;
}
1.3 完整示例
#include <iostream>
#include <vector>
#include <cstdint>
void vectorExample() {
size_t points_cnt = 10;
// 創(chuàng)建并初始化向量
std::vector<uint8_t> occlusions(points_cnt, 0); // 所有元素初始化為0
// 修改元素
for (size_t i = 0; i < points_cnt; ++i) {
occlusions[i] = static_cast<uint8_t>(i * 25);
}
// 添加新元素
occlusions.push_back(255); // 自動(dòng)調(diào)整大小
occlusions.emplace_back(128); // C++11:原地構(gòu)造
// 讀取并顯示所有元素
std::cout << "Vector contents: ";
for (const auto& val : occlusions) {
std::cout << (int)val << " ";
}
std::cout << std::endl;
// 獲取向量信息
std::cout << "Size: " << occlusions.size() << std::endl;
std::cout << "Capacity: " << occlusions.capacity() << std::endl;
// 注意:不需要手動(dòng)釋放內(nèi)存!
// 當(dāng)occlusions離開(kāi)作用域時(shí),vector會(huì)自動(dòng)清理
}
2. malloc:C風(fēng)格的動(dòng)態(tài)內(nèi)存分配
2.1 基本語(yǔ)法與參數(shù)
// 基本語(yǔ)法 T* name = (T*)malloc(count * sizeof(T)); // 實(shí)際示例 unsigned char* occlusions = (unsigned char*)malloc(points_cnt * sizeof(unsigned char));
參數(shù)詳解:
malloc函數(shù)參數(shù):需要分配的字節(jié)數(shù) =points_cnt * sizeof(unsigned char)- 返回值類型轉(zhuǎn)換:
malloc返回void*,需要強(qiáng)制轉(zhuǎn)換為目標(biāo)指針類型 - 指針變量
occlusions:指向分配內(nèi)存起始地址的指針
2.2 如何訪問(wèn)和操作元素
訪問(wèn)單個(gè)元素:
// 使用數(shù)組下標(biāo)語(yǔ)法 occlusions[0] = 255; // 設(shè)置第一個(gè)元素 unsigned char value = occlusions[0]; // 獲取第一個(gè)元素 // 使用指針?biāo)阈g(shù) *(occlusions) = 255; // 等價(jià)于occlusions[0] = 255 *(occlusions + 1) = 128; // 等價(jià)于occlusions[1] = 128 unsigned char value = *(occlusions + 2); // 等價(jià)于occlusions[2]
遍歷所有元素:
// 使用指針遍歷
unsigned char* ptr = occlusions;
for (size_t i = 0; i < points_cnt; ++i) {
*ptr = static_cast<unsigned char>(i * 25);
++ptr; // 移動(dòng)指針
}
// 使用下標(biāo)遍歷
for (size_t i = 0; i < points_cnt; ++i) {
occlusions[i] = i % 256;
}
2.3 完整示例
#include <iostream>
#include <cstdlib> // malloc, free
#include <cstring> // memset
void mallocExample() {
size_t points_cnt = 10;
// 分配內(nèi)存
unsigned char* occlusions =
(unsigned char*)malloc(points_cnt * sizeof(unsigned char));
// 重要:檢查分配是否成功
if (occlusions == nullptr) {
std::cerr << "Memory allocation failed!" << std::endl;
return;
}
// 重要:初始化內(nèi)存(malloc不初始化內(nèi)存?。?
memset(occlusions, 0, points_cnt * sizeof(unsigned char));
// 填充數(shù)據(jù)
for (size_t i = 0; i < points_cnt; ++i) {
occlusions[i] = static_cast<unsigned char>(i * 25);
}
// 顯示內(nèi)容
std::cout << "Malloc array contents: ";
for (size_t i = 0; i < points_cnt; ++i) {
std::cout << (int)occlusions[i] << " ";
}
std::cout << std::endl;
// 重要:必須手動(dòng)釋放內(nèi)存!
free(occlusions);
occlusions = nullptr; // 避免野指針
}
3. 詳細(xì)對(duì)比與選擇指南
3.1 內(nèi)存管理對(duì)比
| 特性 | std::vector | malloc/free |
|---|---|---|
| 初始化 | 默認(rèn)初始化元素 | 不初始化,內(nèi)容是隨機(jī)的 |
| 內(nèi)存釋放 | 自動(dòng)(RAII) | 必須手動(dòng)調(diào)用free() |
| 異常安全 | 是,構(gòu)造函數(shù)失敗會(huì)拋出異常 | 否,需要檢查返回值 |
| 重新分配 | 自動(dòng)(resize/push_back) | 需要realloc(),數(shù)據(jù)可能被移動(dòng) |
3.2 性能與安全對(duì)比
// std::vector的安全性示例
void safeVectorExample() {
std::vector<uint8_t> vec(10);
try {
vec.at(20) = 100; // 拋出std::out_of_range異常
} catch (const std::out_of_range& e) {
std::cout << "安全地捕獲了越界訪問(wèn): " << e.what() << std::endl;
}
// vec[20] = 100; // 未定義行為,可能崩潰或數(shù)據(jù)損壞
}
// malloc的不安全性示例
void unsafeMallocExample() {
unsigned char* arr = (unsigned char*)malloc(10);
// 常見(jiàn)錯(cuò)誤1:忘記檢查分配是否成功
if (arr == nullptr) { /* 必須檢查! */ }
// 常見(jiàn)錯(cuò)誤2:忘記初始化
// arr[0]可能是任意值!
// 常見(jiàn)錯(cuò)誤3:越界訪問(wèn)
arr[15] = 100; // 未定義行為,可能破壞其他內(nèi)存
// 常見(jiàn)錯(cuò)誤4:忘記釋放內(nèi)存(內(nèi)存泄漏)
// free(arr); // 如果忘記這行,內(nèi)存泄漏!
}
4. 高級(jí)用法與技巧
4.1 std::vector的高級(jí)特性
void advancedVectorUsage() {
// 多種初始化方式
std::vector<uint8_t> v1(10, 0xFF); // 10個(gè)元素,每個(gè)都是0xFF
std::vector<uint8_t> v2 = {0, 1, 2, 3, 4}; // 初始化列表(C++11)
std::vector<uint8_t> v3(v1); // 拷貝構(gòu)造
// 內(nèi)存預(yù)分配
v1.reserve(1000); // 預(yù)分配內(nèi)存,避免多次重新分配
// 安全訪問(wèn)
if (!v1.empty()) {
uint8_t first = v1.front(); // 第一個(gè)元素
uint8_t last = v1.back(); // 最后一個(gè)元素
}
// 范圍操作
v1.insert(v1.begin(), {10, 20, 30}); // 開(kāi)頭插入多個(gè)元素
v1.erase(v1.begin() + 1, v1.begin() + 3); // 刪除第2-3個(gè)元素
// C++17:并行算法支持
std::sort(std::execution::par, v1.begin(), v1.end());
}
4.2 malloc的高級(jí)用法與陷阱
void advancedMallocUsage() {
size_t count = 10;
// 正確:使用calloc自動(dòng)初始化為0
unsigned char* arr1 = (unsigned char*)malloc(count * sizeof(unsigned char));
// arr1的所有元素都是0
// 正確:使用realloc調(diào)整大小
arr1 = (unsigned char*)realloc(arr1, count * 2);
// 注意:realloc可能移動(dòng)內(nèi)存,原有指針失效
// 陷阱:錯(cuò)誤的大小計(jì)算
// 錯(cuò)誤:可能溢出
size_t large = 1000000000;
// unsigned char* bad = malloc(large * large); // 溢出!
// 正確:檢查溢出
if (large > SIZE_MAX / sizeof(unsigned char)) {
// 處理溢出錯(cuò)誤
}
// 釋放內(nèi)存
free(arr1);
}
到此這篇關(guān)于C++動(dòng)態(tài)數(shù)組兩種實(shí)現(xiàn)方式詳解(std::vector vs malloc)的文章就介紹到這了,更多相關(guān)C++動(dòng)態(tài)數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中四種強(qiáng)制轉(zhuǎn)換的實(shí)現(xiàn)方法與區(qū)別
這篇文章主要為大家詳細(xì)介紹了C++中四種強(qiáng)制轉(zhuǎn)換的實(shí)現(xiàn)方法與區(qū)別,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-06-06
C++ accumulate函數(shù)詳細(xì)介紹和具體案例
這篇文章主要介紹了C++ accumulate函數(shù)詳細(xì)介紹和具體案例,accumulate是numeric庫(kù)中的一個(gè)函數(shù),主要用來(lái)對(duì)指定范圍內(nèi)元素求和,但也自行指定一些其他操作,如范圍內(nèi)所有元素相乘、相除等2022-08-08
C++實(shí)現(xiàn)的分布式游戲服務(wù)端引擎KBEngine詳解
這篇文章主要詳細(xì)介紹了C++實(shí)現(xiàn)的分布式游戲服務(wù)端引擎KBEngine的概念以及使用方法,非常的實(shí)用,有需要的小伙伴可以參考下2015-03-03
c++ 讓程序開(kāi)機(jī)自動(dòng)啟動(dòng)的方法
這篇文章主要介紹了c++ 讓程序開(kāi)機(jī)自動(dòng)啟動(dòng)的方法,需要的朋友可以參考下2017-09-09
簡(jiǎn)單談?wù)凜++ 頭文件系列之(algorithm)
<algorithm>是c++特有的STL模板的算法頭文件 包含了一些特定的算法函數(shù) 包括sort(),stable_sort(),partical_sort(),nth_element()等常用的算法函數(shù)2017-02-02

