[C/C++安全編程]_[中級]_[如何避免出現野指針]

場景

  1. Rust里不會出現野指針的情況,那么在C++里能避免嗎?

說明

  1. 野指針是指指向無效內存地址的指針,訪問它會導致未定義行為,可能引發程序崩潰、數據損壞或安全漏洞。它是 C/C++ 等手動內存管理語言中的常見錯誤,而 Rust 通過編譯期檢查幾乎徹底消除了這一問題。

  2. 很遺憾,在C++里類成員指針變量是不會自動初始化的,它的指針地址是隨機的,可能為0,可能為無效值。 而全部變量,C++都會默認初始化,局部變量沒初始化就調用的話就會出現編譯警告。沒搞懂C++標準為什么單單留著類成員變量不自動初始化的的問題。

  3. C++11開始,可以使用新語法給成員變量在聲明的時候直接賦值初始化。 這是開發自己手動做的工作,編譯器不會代辦。這種新語法還是減少了很多野指針的問題,比構造函數初始化列表方便多了。

class A
{
public:void* handle_ = NULL;int percent_ = 0;int64_t size_ = 0;
};
  1. C結構體,扁平數據結構可以用{0}賦值初始化。

  2. 總結下,C++的變量初始化規則:

  • 全局變量,在頭文件里聲明的或者在.cpp文件里聲明的都會被編譯器初始化,原始類型是0,指針類型是NULL

  • 類成員變量,靜態和非靜態的成員都不會被編譯器初始化。非靜態成員可以在聲明時就手動賦值初始化,而靜態非const成員必須在類外定義再次賦值初始化。

  • 局部非靜態變量未初始化不能使用,會有編譯警告。

  • 局部靜態變量會被編譯器自動初始化。

  • 非指針類對象不需要賦值初始化,因為它會調用構造函數自動初始化。如果是類成員變量,那么在創建類實例的時候會自動初始化。如果是局部變量,那么也會在聲明時自動調用構造函數初始化。

例子

test-variable-init.cpp

#include <iostream>#include <memory>
#include <string>
#include <vector>
#include <stdint.h>
#include <assert.h>
#include "test-variable-init.h"using namespace std;class A;// 在頭文件里聲明了的全局變量,默認初始化.普通類型是0,指針類型是NULL;
int gLang;void* gWin;// 只在.cpp里聲明的變量,默認初始化.普通類型是0,指針類型是NULL;int gAdd;static long gCount;A* gA;struct RGB
{int r;int g;int b;
};class A
{
public:void* handle_ = NULL;int percent_ = 0;int64_t size_ = 0;RGB rgb_ = {0};string str_;// 沒有初始化string *str2_;private:static const bool bOk_ = false; // 可以直接賦值初始化static string *str3_; // 類靜態成員非const,不能直接賦值初始化。
};string* A::str3_ = nullptr;#define NATIVE_FREE(a,name) shared_ptr<void> a##name(a,[](void* data){ free(data); cout << "call free" << endl; })void TestVariableInit()
{assert(gLang == 0);assert(gWin == NULL);assert(gAdd == 0);assert(gCount == 0);assert(gA == NULL);// 方法的static變量,默認初始化.static int bRun;assert(bRun == 0);// 方法的非static變量,UB(未定義行為),需要手動初始化。int fNumber = 0;  // 如果不手動初始化,編譯錯誤,使用了未初始化的局部變量。cout << "fNumber: " << fNumber << endl;int* fDay = NULL; // 如果不初始化,編譯錯誤,使用了未初始化的局部變量。//*fDay = 10; //RGB rgb2; // 如果不初始化,編譯錯誤,使用了未初始化的局部變量。//cout << "rgb2 r: " << rgb2.r << " g: " << rgb2.g << " b: " << rgb2.b << endl;RGB rgb = {0};cout << "rgb r: " << rgb.r << " g: " << rgb.g << " b: " << rgb.b << endl;// RGB *pRgb; // `pRgb` 如果不初始化,編譯錯誤,使用了未初始化的局部變量。RGB* pRgb = (RGB*)malloc(sizeof(RGB));memset(pRgb, 0, sizeof(RGB));cout << "pRgb: " << pRgb->r << endl;NATIVE_FREE(pRgb, pRgb);A a;cout << "a.size: " << a.size_ << endl;cout << "a.rgb r: " << a.rgb_.r << endl;// 未初始化,也不會編譯報錯。cout << "str2_ address: " << (int)a.str2_ << endl;
}int main()
{// 全部變量和靜態變量都存儲在全局的靜態儲存區。std::cout << "Hello World!\n";cout << "================ TestVariableInit ==============" << endl;TestVariableInit();
}

test-variable-init.h

#pragma onceextern int gLang;extern void* gWin;

輸出

Hello World!
================ TestVariableInit ==============
fNumber: 0
rgb r: 0 g: 0 b: 0
pRgb: 0
a.size: 0
a.rgb r: 0
str2_ address: 0
call free

參考

  1. 如何避免出現懸垂指針

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

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

相關文章

機器學習基礎:從數據到智能的入門指南

一、何謂機器學習? 在我們的日常生活中&#xff0c;機器學習的身影無處不在。當你打開購物軟件&#xff0c;它總能精準推薦你可能喜歡的商品&#xff1b;當你解鎖手機&#xff0c;人臉識別瞬間完成&#xff1b;當你使用語音助手&#xff0c;它能準確理解你的指令。這些背后&a…

steam游戲搬磚項目超完整版實操分享

大家好&#xff0c;我是阿陽&#xff0c;今天再次最詳細的給大家綜合全面的分析講解下steam搬磚&#xff0c;可以點擊后面跳轉往期文章了再次解下阿陽網客&#xff1a;關于steam游戲搬磚項目&#xff0c;我想說&#xff01;最早是21年5月份公開朋友圈&#xff0c;初次接觸是在2…

vue2 面試題及詳細答案150道(21 - 40)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

原生前端JavaScript/CSS與現代框架(Vue、React)的聯系與區別(詳細版)

原生前端JavaScript/CSS與現代框架&#xff08;Vue、React&#xff09;的聯系與區別&#xff0c;以及運行環境和條件 目錄 引言原生前端技術概述 JavaScript基礎CSS基礎 現代框架概述 Vue.jsReact 聯系與相似性主要區別對比運行環境和條件選擇建議總結 引言 在現代Web開發中&…

基于機器視覺的邁克耳孫干涉環自動計數系統設計與實現

基于機器視覺的邁克耳孫干涉環自動計數系統設計與實現 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。 摘要 本文設計并實現了一種基于機器視覺的邁克耳孫干涉環自動計數系統。該系統…

設計模式筆記(1)簡單工廠模式

最近在看程杰的《大話設計模式》&#xff0c;在這里做一點筆記。 書中主要有兩個角色&#xff1a; 小菜&#xff1a;初學者&#xff0c;學生&#xff1b; 大鳥&#xff1a;小菜表哥&#xff0c;大佬。 也按圖中的對話形式 01 簡單工廠模式 要求&#xff1a;使用c、Java、C#或VB…

Vue3 學習教程,從入門到精通,Vue 3 聲明式渲染語法指南(10)

Vue 3 聲明式渲染語法指南 本文將詳細介紹 Vue 3 中的聲明式渲染語法&#xff0c;涵蓋所有核心概念&#xff0c;并通過一個完整的案例代碼進行演示。案例代碼中包含詳細注釋&#xff0c;幫助初學者更好地理解每個部分的功能和用法。 目錄 簡介聲明式渲染基礎 文本插值屬性綁…

React hooks——useReducer

一、簡介useReducer 是 React 提供的一個高級 Hook&#xff0c;用于管理復雜的狀態邏輯。它類似于 Redux 中的 reducer 模式&#xff0c;適合處理包含多個子值、依賴前一個狀態或邏輯復雜的狀態更新場景。與 useState 相比&#xff0c;useReducer 提供更結構化的狀態管理方式。…

SEO中關于關鍵詞分類與布局的方法有那些

前邊我們說到關鍵詞挖掘肯定很重要&#xff0c;但如何把挖掘出來的關鍵詞用好更為重要&#xff0c;下邊我們就來說說很多seo剛入行的朋友比較頭疼的關鍵詞分類問題&#xff0c;為了更直觀的感受搭配了表格&#xff0c;希望可以給大家一些幫助!SEO優化之關鍵詞分類?挖掘出的關鍵…

考研最高效的準備工作是什么

從性價比的角度來說&#xff0c;考研最高效的準備工作是什么呢&#xff1f; 其實就是“卷成績”。 卷學校中各門課程的成績&#xff0c;卷考研必考的數學、英語、政治和專業課的成績。 因為現階段的考研&#xff0c;最看重的仍然是你的成績&#xff0c;特別是初試成績。 有了…

【Linux】基于Ollama和Streamlit快速部署聊天大模型

1.環境準備 1.1 安裝Streamlit 在安裝Streamlit之前&#xff0c;請確保您的系統中已經正確安裝了Python和pip。您可以在終端或命令行中運行以下命令來驗證它們是否已安裝 python --version pip --version一旦您已經準備好環境&#xff0c;現在可以使用pip來安裝Streamlit了。…

Jetpack - ViewModel、LiveData、DataBinding(數據綁定、雙向數據綁定)

一、ViewModel 1、基本介紹 ViewModel 屬于 Android Jetpack 架構組件的一部分&#xff0c;ViewModel 被設計用來存儲和管理與 UI 相關的數據&#xff0c;這些數據在配置更改&#xff08;例如&#xff0c;屏幕旋轉&#xff09;時能夠幸存下來&#xff0c;ViewModel 的生命周期與…

Go并發聊天室:從零構建實戰

大家好&#xff0c;今天我將分享一個使用Go語言從零開始構建的控制臺并發聊天室項目。這個項目雖然簡單&#xff0c;但它麻雀雖小五臟俱全&#xff0c;非常適合用來學習和實踐Go語言強大的并發特性&#xff0c;尤其是 goroutine 和 channel 的使用。 一、項目亮點與功能特性 …

瘋狂星期四第13天運營日報

網站運營第13天&#xff0c;點擊觀站&#xff1a; 瘋狂星期四 crazy-thursday.com 全網最全的瘋狂星期四文案網站 運營報告 昨日訪問量 昨天大概60個ip, 同比上個星期是高點的&#xff0c;但是與星期四差別還是太大了。&#x1f602; 昨日搜索引擎收錄情況 百度依舊0收錄 …

吳恩達《AI for everyone》第二周課程筆記

機器學習項目工作流程以Echo/Alexa&#xff08;語音識別AI&#xff09;作為例子解釋&#xff1a; 1. collect data 收集數據——人為找很多人說 Alexa&#xff0c;并錄制音頻&#xff1b;并且還會讓一群人說其他詞語&#xff0c;比如hello 2. train model 訓練模型——用機器學…

uniapp props、$ref、$emit、$parent、$child、$on

1. uniapp props、ref、ref、ref、emit、parent、parent、parent、child、$on 1.1. 父組件和子組件 propsPage.vue導入props-son-view.vue組件的時候,我們就稱index.vue為父組件依次類推,在vue中只要能獲取到組件的實例,那么就可以調用組件的屬性或是方法進行操作 1.2. pr…

4、ubuntu | dify創建知識庫 | 上市公司個股研報知識庫

1、創建知識庫步驟 創建一個知識庫并上傳相關文檔主要涉及以下五個關鍵步驟&#xff1a; 創建知識庫&#xff1a;首先&#xff0c;需要創建一個新的知識庫。這可以通過上傳本地文件、從在線資源導入數據或者直接創建一個空的知識庫來實現。 指定分段模式&#xff1a;接下來是…

Kubernetes中為Elasticsearch配置多節點共享存儲

在Kubernetes中為Elasticsearch配置多節點共享存儲(ReadWriteMany)需結合存儲后端特性及Elasticsearch架構設計。 由于Elasticsearch默認要求每個節點獨立存儲數據(ReadWriteOnce),直接實現多節點共享存儲需特殊處理。 ??方案一:使用支持ReadWriteMany的存儲后端(推薦…

SpringBoot熱部署與配置技巧

配置文件SpringBoot 的熱部署Spring為開發者提供了一個名為spring-boot-devtools的模塊來使SpringBoot應用支持熱部署&#xff0c;提高開發者的開發效率&#xff0c;無需手動重啟SpringBoot應用相關依賴&#xff1a;<dependency> <groupId>org.springframework.boo…

Python與C#的三元運算符的寫法區別

一、語法結構對比??PyTorch示例??dev torch.device("cuda:0" if torch.cuda.is_available() else "cpu")??邏輯??&#xff1a;若torch.cuda.is_available()為真&#xff0c;則返回"cuda:0"&#xff0c;否則返回"cpu"。??作…