簡體   English   中英

使用變量定義數組大小和使用新的運算符c ++有什么區別?

[英]What's the difference between using a variable to define array size and using the new operator c++?

我基於“ http://www.cplusplus.com/doc/tutorial/dynamic/ ”上的官方教程,學習了Java的基礎知識以及以前的Java經驗。 本教程介紹了運算符“ new”,作為在運行時定義數組大小的一種方法。 但是,這感覺像是無用的加法,因為通過執行以下操作,我可以輕松地使用變量定義數組的大小

int numbers [size];

int * numbers = new int [size];

通過我自己的測試,我已經意識到使用new運算符可以遍歷預分配的內存大小(當我用size = 5初始化它時,我可以寫到numbers [7]),而第一行代碼卻沒有。 關於此運算符,我有三個基本問題:

  1. 上面兩行代碼有什么區別?
  2. 寫入我未分配的數組中的內存中的指針地址是否有危險?
  3. 如果這樣做很危險,除了手動設置(或使用庫)鏈接列表之外,我可以使用什么替代方法(如果有)來設置列表?

上面兩行代碼有什么區別?

假設size是一個常量表達式,則不同之處是第一個示例分配在堆棧上,而第二個示例分配在堆上,您需要記住將其delete []

寫入我未分配的數組中的內存中的指針地址是否有危險?

寫越界是不確定的行為,但是如果您在界界內,則可以:

constexpr int size = 5;
int arr[size];
arr[0] = 2;

如果這樣做很危險,我可以使用什么替代方法

使用std::vector

std::vector<int> arr;
 int numbers [size]; 

 int * numbers = new int [size]; 

首先,在標准C ++中,要求size的值是已知的,並在編譯時固定。 第二個允許在運行時確定size值(例如,基於用戶輸入)。

一些編譯器允許將第一種形式與size作為變量一起使用,但這不是標准的C ++。 這種可變長度數組是C(從1999年開始)的一項功能,某些C ++編譯器將其作為非標准擴展來支持。 其他C ++編譯器將診斷錯誤(按照C ++標准的要求)。

第一個的分配方式取決於上下文。 例如;

  • 如果在函數外部(例如,在文件范圍內),它將被靜態分配,並且將在程序運行時一直存在。
  • 如果在塊內(例如,在函數中), arr將具有自動存儲持續時間,並且在封閉的塊末尾將不存在(例如,函數返回時)。
  • 如果是structclass類型的成員,則在創建該structclass的實例時將創建該數組。

上面的前兩個有時有些不正確,有時說是在“堆棧”上創建的。 但是,C ++標准不需要-“堆棧”是與操作系統和運行時環境關聯的實現細節。

據說第二個動態分配內存(使用operator new )。 內存將一直存在,直到將其顯式釋放為止(例如,使用相應的運算符delete )。

寫入我未分配的數組中的內存中的指針地址是否有危險?

是。 該行為由C ++標准未定義。 實際上,它似乎可以正常工作。 它還可能產生不良影響,例如程序中毒數據或重新格式化硬盤驅動器。 在令人討厭的情況下,它似乎可以在您的測試中正常工作,而只有付費客戶運行時,它才會產生不想要的效果之一。 這種情況往往使脾氣暴躁的客戶。

無論是使用指針還是使用數組,行為都是同樣不確定的。 將值分配給具有五個元素的數組的第十個元素會產生不確定的行為,而與數組的創建方式無關(例如,在兩個選項中的任何一個中)。

如果這樣做很危險,除了手動設置(或使用庫)鏈接列表之外,我可以使用什么替代方法(如果有)來設置列表?

在C ++中,有標准容器。 查找vector (在標准標題<vector> )作為示例。 顯然,可能會錯誤地使用標准容器(並產生不良影響),但與使用數組或指針相比,使用標准容器更容易避免出現問題。

標准容器還可以自動處理內存分配和釋放-作為程序員,您無需直接管理動態內存(例如,在不再需要時忘記釋放內存)。

上面兩行代碼有什么區別?

不同之處在於,C ++中不允許使用第一個。 一些編譯器會允許它,並且在提供特殊標志時可能會發出警告,而其他編譯器會視其為“獲取”。

第二個是要走的路,無論您使用哪種編譯器,幾乎都會做同樣的事情。

寫入我未分配的數組中的內存中的指針地址是否有危險?

是的。 行為是不確定的 如果您在運行時沒有遇到任何異常,請不要將其視為好事,因為遲早會有一些意外中斷。

如果這樣做很危險,除了手動設置(或使用庫)鏈接列表之外,我可以使用什么替代方法(如果有)來設置列表?

您是否正在尋求一種訪問不屬於您的內存的替代方法? 答案是不要做!

您可以使用C ++的一個容器代替創建東西列表。 對於內置的鏈表數據結構,請使用std::liststd::forward_list 對於隨機訪問容器, std::vector是一個很好的開始,但是如果您提前知道大小(即在運行時之前),則可以使用std::array

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM