2015-10-18 76 views
0

我被賦予了一個創建dll的任務,我需要爲結構分配和釋放內存。不幸的是,我不知道如何檢查代碼是否正常工作。結構的C++內存分配

#pragma once 

#include "stdafx.h" 
#include "RandomBlockHeader.h" 
#include <iostream> 
#include <ctime> 

using namespace std; 

namespace RandBlock { 
unsigned long RandBlockFuncs::GenerateRandomBlock(RANDOM_BLOCK ** ppRandomBlock) { 
    try { 
     srand(time(NULL)); 
     ppRandomBlock = (RANDOM_BLOCK**)malloc(sizeof(RANDOM_BLOCK)); 
     int random = rand() % 129; 
     (**ppRandomBlock).ulRandomLen = random; 
     (**ppRandomBlock).pRandomData = new unsigned char[random]; 
     for (int i = 0; i < random; i++) { 
      (**ppRandomBlock).pRandomData[i] = (char)(rand() % 256); 
     } 
     return 0; 
    } 
    catch (exception& e) { 
     return -1; 
    } 
} 

unsigned long FreeRandomBlock(RANDOM_BLOCK * pRandomBlock) { 
    try { 
     delete pRandomBlock; 
     return 0; 
    } 
    catch (exception& e) { 
     return -1; 
    } 
} 
} 

任何人都可以指出我可能有哪些錯誤嗎?這是爲兩個指針結構分配內存的正確方法嗎?

回答

0
ppRandomBlock = (RANDOM_BLOCK**)malloc(sizeof(RANDOM_BLOCK)); 

不好。我懷疑它需要:

*ppRandomBlock = (RANDOM_BLOCK*)malloc(sizeof(RANDOM_BLOCK)); 

更重要的是,因爲使用的是C++,功能界面更改爲:

unsigned long RandBlockFuncs::GenerateRandomBlock(RANDOM_BLOCK*& ppRandomBlock) { ... } 

然後,功能會顯得更清潔(不要使用malloc在全部):

unsigned long RandBlockFuncs::GenerateRandomBlock(RANDOM_BLOCK*& ppRandomBlock) { 
    try { 
     srand(time(NULL)); 
     ppRandomBlock = new RANDOM_BLOCK; 
     int random = rand() % 129; 
     (*ppRandomBlock).ulRandomLen = random; 
     (*ppRandomBlock).pRandomData = new unsigned char[random]; 
     for (int i = 0; i < random; i++) { 
     (*ppRandomBlock).pRandomData[i] = (char)(rand() % 256); 
     } 
     return 0; 
    } 
    catch (exception& e) { 
     return -1; 
    } 
} 
0

我假定RANDOMBLOCK是包含struct類型(至少)兩個構件 - ulRandomLen這是類型的(不承認它的名字)和pRandomData,它的類型指向unsigned char

基於這些假設,代碼中存在以下問題

  • 該函數有返回類型的unsigned long並返回-1。 (幸運的是)有一個明確的效果 - 它返回一個unsigned long可以表示的最大值。但是,這可能不是調用者期望的。
  • 每次調用函數時,代碼都會調用srand()。這將 - 除非程序運行很長時間 - 重新初始化隨機數種子,並導致rand()返回相同的隨機值序列。在第一次調用rand()之前,您需要確保srand()僅在COMPLETE程序中稱爲ONCE。
  • 聲明ppRandomBlock = (RANDOM_BLOCK**)malloc(sizeof(RANDOM_BLOCK))需要分配sizeof(RANDOMBLOCK *)而不是sizeof(RANDOM_BLOCK)。更好的是,用ppRandomBlock = new (RANDOM_BLOCK *)替換聲明,並避免需要擔心尺寸。
  • 上述聲明(無論是否修正)的問題是它不分配RANDOMBLOCK,並且*ppRandomBlock未初始化。這會導致所有通過**ppRandomBlock訪問具有未定義的行爲。所以,它需要跟一個*ppRandomBlock = new RANDOMBLOCK
  • 儘管pRandomData[i]的類型爲unsigned char,但內部for循環具有語句(*ppRandomBlock).pRandomData[i] = (char)(rand() % 256)。它是實施定義的,不管是直接charsigned還是unsigned。如果是signed,則不能保證最大值a char能夠保持大於127的值。這導致轉換爲char具有未定義的行爲。

作爲部分修復,更改RANDOMBLOCK以包含std::vector<unsigned char> RandomData並消除構件ulRandomLenpRandomData完全。然後更改功能

unsigned long RandBlockFuncs::GenerateRandomBlock(RANDOM_BLOCK*& ppRandomBlock) 
{ 
    try 
    { 
     // assume `srand()` has been called, for example, in main() 

     ppRandomBlock = new RANDOM_BLOCK; 
     int random = rand() % 129; 
     ppRandomBlock.RandomData.resize(random); 
     for (int i = 0; i < random; i++) 
     { 
     ppRandomBlock.RandomData[i] = (unsigned char)(rand() % 256); 
     } 
     return 0; 
    } 
    catch (exception& e) 
    { 
     return -1; 
    } 
} 

注意,上面並沒有與unsigned返回類型和-1返回值修復該問題。

更一般地說,OP代碼中的首要問題是它是一些C代碼(裝飾)的粗略翻譯成C++。即使它是很好的C代碼,好的C技術並不總是很好的C++技術,反之亦然。並且,就其而言,原始代碼涉及C中的不良技術。

將代碼完全重寫爲使用C++庫特性(我已經演示了其中的一個元素,其中更多可能)會更好,並且根本不直接使用運營商new