簡體   English   中英

C ++ malloc / realloc奇怪的行為

[英]C++ malloc/realloc weird behavior

我正在編寫一個動態數組供我自己使用,我想用0預設。

template <class T>
dynArr<T>::dynArr()
{
rawData = malloc(sizeof(T) * 20); //we allocate space for 20 elems
memset(this->rawData, 0, sizeof(T) * 20); //we zero it!
currentSize = 20;
dataPtr = static_cast<T*>(rawData); //we cast pointer to required datatype.
}

這部分工作 - 循環迭代與dereferencind dataPtr工作得很好。 零。

然而,重新分配行為(在我看來)至少有點奇怪。 首先,您必須查看重新分配代碼:

template <class T>
void dynArr<T>::insert(const int index, const T& data)
{

    if (index < currentSize - 1)
    {
        dataPtr[index] = data; //we can just insert things, array is zero-d
    }

    else
    {
        //TODO we should increase size exponentially, not just to the element we want

        const size_t lastSize = currentSize; //store current size (before realloc). this is count not bytes.

        rawData = realloc(rawData, index + 1); //rawData points now to new location in the memory
        dataPtr = (T*)rawData;
        memset(dataPtr + lastSize - 1, 0, sizeof(T) * index - lastSize - 1); //we zero from ptr+last size to index

        dataPtr[index] = data;
        currentSize = index + 1;
    }

}

很簡單,我們將數據重新分配到索引+ 1,並將尚未歸零的內存設置為0。

至於測試,我首先在該陣列的第5位插入5。 預期的事情發生了 - 0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

然而,插入其他東西,如插入(30,30)給了我奇怪的行為:

0, 0, 0, 0, 0, 5, 0, -50331648, 16645629, 0, 523809160, 57600, 50928864, 50922840, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,

怎么了,我不明白這里的意思嗎? 不應該realloc考慮所有20個先前設置的內存字節? 這里有什么巫術。

問題1:

您在realloc調用中使用了錯誤的大小。 將其更改為:

rawData = realloc(rawData, sizeof(T)*(index + 1)); 

如果rawData的類型為T* ,則更喜歡

rawData = realloc(rawData, sizeof(*rawData)*(index + 1)); 

問題2:

以下的最后一個詞是不對的。

memset(dataPtr + lastSize - 1, 0, sizeof(T) * index - lastSize - 1); 

你需要使用:

memset(dataPtr + lastSize - 1, 0, sizeof(T) * (index - lastSize - 1));
                               //  ^^              ^^
                               // size      *  The number of objects 

問題3:

使用分配給dataPtr

dataPtr[index] = data;

使用mallocrealloc獲取內存時出現問題。 malloc系列函數只返回原始內存。 它們不初始化對象。 分配給未初始化的對象是所有非POD類型的問題。

問題4:

如果T是具有虛擬成員函數的類型,則使用memset將內存清零將極有可能導致問題。


建議解決所有問題:

因為你在C ++領域,所以使用newdelete會好得多。

template <class T>
dynArr<T>::dynArr()
{
   currentSize = 20;
   dataPtr = new T[currentSize];
   // Not sure why you need rawData
}

template <class T>
void dynArr<T>::insert(const int index, const T& data)
{
   if (index < currentSize - 1)
   {
      dataPtr[index] = data;
   }

   else
   {
      const size_t lastSize = currentSize;
      T* newData = new T[index+1];
      std::copy(dataPtr, dataPtr+lastSize, newData);
      delete [] dataPtr;
      dataPtr = newData;
      dataPtr[index] = data;
      currentSize = index + 1;
   }
}

請注意,僅當T是默認可構造時,建議的更改才有效。

這也將解決上面概述的問題3和4。

暫無
暫無

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

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