为三重指针分配内存

Posted

技术标签:

【中文标题】为三重指针分配内存【英文标题】:Allocating memory for triple pointer 【发布时间】:2009-02-12 10:54:38 【问题描述】:

函数somefunction() 将三重指针作为参数。

int somefunction(tchar ***returnErrors);

如何为returnErrors参数分配内存?

【问题讨论】:

函数应该做什么?你有它的文档吗? 【参考方案1】:

猜测。 . .

您可以将 returnErrors 视为指向字符串数组的指针。

    第一个 * 实现指向数组的指针 的 tchar (或单个字符串 字符) 第二个 * 实现了一个指向 字符串数组。 最后一个 * 是您可以更改的 returnErrors 并传回新的 记忆。

为此释放内存(愚蠢的例子,在 SomeFunction 中分配内存)

tchar ** errors;
// Oops it appears I need to pass back two error strings (+ 1 for null on end, so we know there are no more - thanks tlholaday)
errors = malloc(sizeof(tchar*) * 3);

// the first string has length 20 (+ 1 for null terminator)
errors[0] = malloc(sizeof(tchar) * 21);

// the second string has length 30 (+ 1 for null terminator)
errors[1] = malloc(sizeof(tchar) * 31);

// ensure the last is null
errors[2] = 0;

*returnErrors = errors;

注意:调用函数需要知道 SomeFunction 已分配内存并需要释放它。

【讨论】:

您可能需要 errors = malloc(sizeof(tchar*) * 3) 以便您可以在 errors[2] 中添加一个空终止符以表示“没有更多字符串”。【参考方案2】:

你是在实现 somefunction还是调用 somefunction?

如果你正在调用某个函数,很可能某个函数会分配内存,所以你需要做的就是将它传递给一个安全的地方以便在之后进行涂鸦和清理。

tchar **theErrors = 0; // a vector of tchar vectors.
somefunction(&theErrors); 
if (theErrors) 
  // use the error values
  // free the memory somehow - this is for a null-terminated convention
      tchar **victim = theErrors;
      while (*victim) delete[](*victim++);
      delete[] theErrors;

注意:我使用 0 和 delete[] 而不是 NULL 和 free,因为标签上写着 c++。

【讨论】:

我的猜测是该函数返回分配给Errors数组的以NULL结尾的字符串的数量。 我想象该函数会返回一个 HRESULT,带有 S_OK、S_FALSE、E_FAIL、E_NOT_IMPLEMENTED 等。这个问题让我想起了为什么我更喜欢 ... somefunction( std::vector<:string>> &);【参考方案3】:

这取决于“somefunction”的期望。您必须对此进行调查!

它可能需要一个指向固定大小的 2 维数组,或 3 维常规数组的指针,或者 ???

在我提到的情况下,代码可能看起来像

tchar errors[SIZE1][SIZE2];
somefunction( &errors );

tchar errors[SIZE1][SIZE2][SIZE3];
somefunction( errors );

【讨论】:

或者可能有几十种其他可能性。如果没有somefunction 的文档(或来源),完全不可能知道预期会发生什么。 对。但我认为简单地回答“这取决于”并没有多大用处! :-)【参考方案4】:

有谁知道如何分配 returnErrors 参数的内存?

这个问题太笼统了,一般情况下无法回答。以下只是调用它的可能代码 sn-p 的示例。

tchar foo;
tchar * p_foo = &foo;
tchar ** pp_foo = &p_foo;
tchar *** ppp_foo = &pp_foo;
somefunction(ppp_foo);

只是评论:我会认为您的函数签名不安全,因此即使它少了一颗星也会有代码异味。

另外,请注意:

指针永远不是数组。它是一个 包含值的变量 内存地址,或 NULL。 指针包含的地址 并不总是对应于 数组的起始地址。诠释** p 并不总是指 int[][] 的起始地址。 一个指针,其值包含 数组的起始地址不是 将此数组作为 功能参数。相反,可以使用对数组类型的引用。 在 C++ 中,数组通常不是包含一组相关值的最佳方式。应考虑 std::vector 和其他 STL 容器。 (但是你的问题有两种语言,C 和 C++,作为标签;当然这只适用于后一种可能性。为什么有两个标签?)

【讨论】:

【参考方案5】:

我会使用像你的 someFunction() 这样的函数有两个用例。

初始化:


    tchar **returnErrors;

    initErrors(tchar &returnErrors);
    /* now returnErrors has a place in memory*/


int initErrors(tchar ***returnErrors)

    *returnErrors = malloc(sizeof(tchar *) * SIZE1)

     for (i = 0; i < NUM_ELEMENTS; i++)
         (*returnErrors)[i] = malloc(sizeof(tchar) * SIZE2);

    /*add checks for malloc failures*/

数组传递给函数:


    returnErrors[SIZE1][SIZE2][SIZE3];

    someFunciton(returnErrors);


int someFunciton(tchar ***returnErrors)

    /*assuming that this is a valid index*/
    tchar x = returnErrors[1][1][1]; 
    /*return errors is used as a triple array*/

【讨论】:

【参考方案6】:

如果您还没有该类型的构造,则三重指针没有任何意义。我宁愿推荐使用一个类——或者至少是一个标准容器。但如果你一定要知道,就这么简单

tchar ***pointer = (tchar***) malloc(sizeof(tchar**) * amount);

【讨论】:

我认为您缺少一个 *。它应该是 (tchar***) malloc(... . 还有一件事。移除强制转换并确保包含 stdlib.h。【参考方案7】:

我倾向于同意tlholaday 的猜测,修改后的函数可能返回它分配的错误数。

tchar **theErrors = 0; // a vector of tchar vectors.
int nErrors = somefunction(&theErrors); 
if (nErrors > 0) 
     for (int i = 0; i < nErrors; ++i)
     
         printf(theErrors[i]);
         free(theErrors[i]);
     
     free(theErrors);

请注意,您是使用 free 还是 delete[] 将取决于首先分配内存的方式。

【讨论】:

以上是关于为三重指针分配内存的主要内容,如果未能解决你的问题,请参考以下文章

C 语言二级指针作为输入 ( 自定义二级指针内存 | 为 二级指针 分配内存 - 存放 一维指针 | 为每个 一级指针 分配内存 | 释放二维指针内存 )

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

C中的指针:分配内存与赋值VS分配内存而不赋值

C++中内存分配问题

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

Keil C51 在编译时不会为结构指针分配内存