结构体的c++内存分配
C++ memory allocation for a structure
我被赋予了一个任务来创建dll,我需要为结构分配和释放内存。不幸的是,我不知道如何检查代码是否有效。
#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;
}
}
}
谁能指出我哪里可能有错误?这是一个正确的方式来分配内存的两个指针结构?
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;
}
}
我假设RANDOMBLOCK
是struct
类型,包含(至少)两个成员- ulRandomLen
类型为int
(不考虑其名称),pRandomData
类型为指向unsigned char
的指针。
基于这些假设,代码有以下问题
- 函数返回类型为
unsigned long
,返回-1
。这(幸运的是)具有良好定义的效果—它返回unsigned long
可以表示的最大值。然而,这可能不是调用者所期望的。 - 每次调用该函数时,代码都会调用
srand()
。这将——除非程序运行很长时间——重新初始化随机数种子,并导致rand()
返回相同的随机值序列。你需要确保srand()
在COMPLETE程序中只被调用一次,在rand()
的第一次调用之前。 - 语句
ppRandomBlock = (RANDOM_BLOCK**)malloc(sizeof(RANDOM_BLOCK))
需要分配sizeof(RANDOMBLOCK *)
,而不是sizeof(RANDOM_BLOCK)
。更好的是,将语句替换为ppRandomBlock = new (RANDOM_BLOCK *)
,并且不必担心大小问题。 - 前面的语句的问题(无论是否固定)是,它不分配
RANDOMBLOCK
,并留下*ppRandomBlock
未初始化。这导致所有通过**ppRandomBlock
的访问都有未定义的行为。因此,它需要后跟一个*ppRandomBlock = new RANDOMBLOCK
。 - 内部的
for
循环有一条语句(*ppRandomBlock).pRandomData[i] = (char)(rand() % 256)
,尽管pRandomData[i]
的类型是unsigned char
。直接的char
是signed
还是unsigned
是由实现定义的。如果设置为signed
,则不能保证char
能够保存的最大值大于127
。这导致转换到char
有未定义的行为。
作为部分修复,将RANDOMBLOCK
更改为包含std::vector<unsigned char> RandomData
,并完全消除ulRandomLen
和pRandomData
成员。然后将函数更改为
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
。
相关文章:
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 在函数中分配内存时出现问题
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- constexpr new 如何分配内存?
- 在构造函数中分配内存失败是如何冒泡的
- LLVM 传递以在特定地址分配内存
- CudaMalloc 在分配内存时失败
- 为什么它在不分配内存的情况下工作正常
- 为什么在正确解除分配内存时出现内存泄漏?
- 如何通过 malloc 为队列数组分配内存?
- vector是否为std::移动的对象连续分配内存
- 删除类成员的动态分配内存的最佳方法是什么
- 唯一指针是否在堆或堆栈上分配内存?
- 如果不分配内存,我如何能够为变量创建和分配值?
- std::initializer_list 堆是否分配内存?
- 如何按顺序或在指定的地址分配内存?
- 是否可以使用 malloc 为类对象分配内存?
- 迭代器是否分配内存(如指针)?