释放分配给 void 指针数组的内存

Posted

技术标签:

【中文标题】释放分配给 void 指针数组的内存【英文标题】:Freeing memory allocated to an array of void pointers 【发布时间】:2008-10-15 20:19:18 【问题描述】:

我声明了一个 void 指针数组。每个都指向一个任意类型的值。void **values; // Array of void pointers to each value of arbitary type

初始化值如下:


    values = (void**)calloc(3,sizeof(void*));
    //can initialize values as: values = new void* [3];
    int ival = 1;
    float fval = 2.0;
    char* str = "word";
    values[0] = (void*)new int(ival);
    values[1] = (void*)new float(fval);
    values[2] = (void*)str;

    //Trying to Clear the memory allocated
    free(*values); 
    //Error: *** glibc detected *** simpleSQL: free(): invalid pointer: 0x080611b4
    //Core dumped
    delete[] values*;
    //warning: deleting 'void*' is undefined
    //Similar Error.

现在如何释放/删除为值分配的内存(空指针数组)?

【问题讨论】:

可能你的意思是:values = (void**)calloc(3,sizeof(void*)); 【参考方案1】:

我怀疑问题出在您分配valuesvalues = (void*)calloc(3,sizeof(void)) 的方式上。那应该是sizeof(void *) 而不仅仅是sizeof(void)

sizeof(void) 可能为零或其他没有意义的东西,所以你并没有真正分配任何内存开始......分配工作只是运气不好,然后当你弹出错误时尝试释放内存。

编辑:您还通过在 C++ 风格 new/delete 和 C 风格 malloc/free 之间交替来自找麻烦。只要你不deletemalloc'ed 或freenew'ed,就可以同时使用它们,但如果你不这样做,你会在脑海中混淆它们像这样走。

【讨论】:

很好地抓住了 void * 与 void 的东西。我没注意到。 谢谢! sizeof(void) 真的在我脑海里敲响了警钟:-)【参考方案2】:

您有 3 个需要以 2 种不同方式释放的动态分配的东西:

delete reinterpret_cast<int*>( values[0]);    
delete reinterpret_cast<float*>( values[1]);

free( values); // I'm not sure why this would have failed in your example, 
               //    but it would have leaked the 2 items that you allocated 
               //    with new

请注意,由于str 不是动态分配的,它不应该(实际上不能)被释放。

几点说明:

我假设sizeof(void) 本来是sizeof(void*) 因为你不会编译 我不会说什么 你看似随机的演员阵容,除了 它看起来像准备好的代码 一般用于灾难

【讨论】:

我必须同意迈克关于“灾难”部分的观点。致 OP:你是想用 C 还是 C++ 编程?在 C 中,强制转换为 void* 通常是有意义的,但您必须知道自己在做什么。在 C++ 中,您似乎在做的事情还有其他成语。决定你要编程的语言:) 我不知道如何在 c++ 中创建一个包含不同数据类型的数据的容器。尝试使用向量,但你只能在其中包含相同类型的数据。任何人都可以提出其他方法来完成上述操作吗? 有多种不同的方法可以为异构类型制作容器。有关在 C++ 中执行此操作的几种方法,请参阅此常见问题解答:parashift.com/c++-faq-lite/containers.html#faq-34.4 “我不知道如何在 c++ 中创建一个包含不同数据类型的数据的容器”——这本身就是一个很好的 SO 问题。我认为可能有一些有趣的答案超出(或至少更详细)C++ FAQ 答案。 我最喜欢的答案是“使用动态语言(如 Perl、Python、Ruby)而不是 C 或 C++”。说真的,当您创建了一个体面的基础架构来管理内存和自省任意类型的数组时,您实际上已经重新创建了其中一种语言。 :)【参考方案3】:

这是 boost::any 类的完美情况 此外,您可能需要考虑使用向量而不是分配自己的内存。

std::vector<boost::any>   data;
boost::any i1 = 1; // add integer
data.push_back(i1);

boost::any f1 = 1.0; // add double
data.push_back(f1);

data.push_back("PLOP"); // add a char *

std:: cout << boost::any_cast<int>(data[0]) + boost::any_cast<double>(data[1])
           << std::endl;

回到你原来的代码,主要问题是:

values = (void*)calloc(3,sizeof(void));

// This should  have been
void** values = (void**)calloc(3,sizeof(void*));

// Freeing the members needs care as you need to cast them
// back to the correct type before you release the memory.

// now you can free the array with
free(values);

另请注意:虽然在同一段代码中同时使用 new/delete 和 calloc/free 并不违法,但这是不受欢迎的。主要是因为很容易把事情搞混,这可能是致命的。

【讨论】:

现在真是太棒了。我已经看到了很多关于 Boost 的好东西,它可能会说服我再次使用 C++。【参考方案4】:

你正在混合 new 和 *alloc()。这是一个禁忌,可能会导致不确定的结果。

【讨论】:

仅当您不小心时(诚然非常小心)。混合 malloc/delete 是这里的问题。【参考方案5】:

如果你在 C 中做事,我不确定你为什么要使用 new(在这里引用标签)。

我会 malloc 我需要的数组的各个部分,然后我想在完成后释放它们。你不能释放你没有首先 malloc 的东西。你也不能删除空指针。

【讨论】:

【参考方案6】:

请注意,您也没有删除值 [0] 和值 [1],这是内存泄漏,但是根据您的设计,您不能释放值 [2],因为它是指向您的 .data 部分的指针。

【讨论】:

【参考方案7】:

您必须跟踪最初 calloc'd 的 void* 数量,并迭代它们,释放每个,然后释放原始值变量。

该死的格式...(预览工作正常)。

int ct = 3;
values = (void*)calloc(ct,sizeof(void));
//can initialize values as: values = new void* [3];
int ival = 1;
float fval = 2.0;
char* str = "word";
values[0] = (void*)new int(ival);
values[1] = (void*)new float(fval);
values[2] = (void*)str;

for ( int i = 0; i < ct; i++ ) [
    delete( values[i] );

free( values );

【讨论】:

废话...拜托,有人告诉我如何格式化一个块看起来像代码。 每行前放4个空格 说真的,什么都不做,它会格式化代码....太棒了。感谢您的帮助

以上是关于释放分配给 void 指针数组的内存的主要内容,如果未能解决你的问题,请参考以下文章

C 语言结构体 ( 结构体中嵌套一级指针 | 分配内存时先 为结构体分配内存 然后再为指针分配内存 | 释放内存时先释放 指针成员内存 然后再释放结构头内存 )

基本 CUDA 指针/数组内存分配和使用

void 类型的数组

怎么用new定义一个类数组,并且释放内存

指针和动态内存分配和释放

C 语言结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )