2015-10-18 75 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