1

我很想知道如何通过函数分配数据,并且在函数返回后数据仍然被分配。这既适用于基本类型(int、char**)也适用于用户定义类型。下面是两个代码片段。两者都在函数内进行分配,尽管在返回之后分配进行。

int* nCheck = NULL;
int nCount = 4;

CallIntAllocation(nCheck, nCount);

nCheck[1] = 3; // Not allocated!
...

CallIntAllocation(int* nCheck, int nCount)
{

    nCheck = (int*)malloc(nCount* sizeof(int));
    for (int j = 0; j < nCount; j++)
        nCheck[j] = 0;
}

用户定义类型的行为与以前相同:

typedef struct criteriatype
{
    char szCriterio[256];
    char szCriterioSpecific[256];
} _CriteriaType;

typedef struct criteria
{
    int nCount;
    char szType[128];
    _CriteriaType* CriteriaType;
} _Criteria;

...
_Criteria* Criteria;
AllocateCriteria(nTypes, nCriteria, Criteria);
...

void AllocateCriteria(int nTypes, int nCriteria[], _Criteria* Criteria)
{
    int i = 0;
    int j = 0;

    Criteria = (_Criteria*)malloc(nTypes * sizeof(_Criteria));

    for (i = 0; i < nTypes; i ++)
    {
        // initalise FIRST the whole structure
        // OTHERWISE the allocation is gone
        memset(&Criteria[i],'\0',sizeof(_Criteria));

        // allocate CriteriaType
        Criteria[i].CriteriaType = (_CriteriaType*)malloc(nCriteria[i] * sizeof(_CriteriaType));

        // initalise them
        for (j = 0; j < nCriteria[i]; j ++)
            memset(&Criteria[i].CriteriaType[j],'\0',sizeof(_CriteriaType));


    }

}

有任何想法吗?我想我需要将指针作为参考传递,但我该怎么做?

在此先感谢,防晒霜

4

5 回答 5

5

使用返回?

Criteria *
newCriteria() {
   Criteria *criteria = malloc(..);
   ...
   return criteria;
}

/* the caller */
Criteria *c1 = newCriteria();
Criteria *c2 = newCriteria();

编辑

调用者负责调用 free()

于 2009-06-15T08:01:10.453 回答
4

您有 2 种可能的解决方案:

 int *CallIntAllocation(int nCount)
 {

     int *nCheck = (int*)malloc(nCount* sizeof(int));
     for (int j = 0; j < nCount; j++)
         nCheck[j] = 0;

     return nCheck;
 }

 int* nCheck = NULL;
 int nCount = 4;

 nCheck = CallIntAllocation(nCount);

或者如果你想分配数组,你应该传递一个指向 int* 的指针:

 void CallIntAllocation(int **nCheck, int nCount)
 {

     *nCheck = (int*)malloc(nCount* sizeof(int));
     for (int j = 0; j < nCount; j++)
         *nCheck[j] = 0;
 }

 int* nCheck = NULL;
 int nCount = 4;

 CallIntAllocation(&nCheck, nCount); 
于 2009-06-15T08:19:20.270 回答
3

直接回答你的问题:

int* nCheck = NULL;
int nCount = 4;

CallIntAllocation(&nCheck, nCount);

nCheck[1] = 3; // allocated!
...

void CallIntAllocation(int** pnCheck, int nCount)
{
    int* nCheck = NULL;
    nCheck = (int*) malloc(nCount * sizeof(*nCheck));
    for (int j = 0; j < nCount; j++)
        nCheck[j] = 0;
    *pnCheck = nCheck;
}

但我会建议这样做:

nCheck = CallIntAllocation(nCount);

nCheck[1] = 3; // allocated!
...
int *CallIntAllocation(int nCount)
{
    int * nCheck
    nCheck = (int*) malloc(nCount * sizeof(*nCheck));
    for (int j = 0; j < nCount; j++)
        nCheck[j] = 0;
    return nCheck;
}
于 2009-06-15T08:44:51.160 回答
2

它不起作用的原因是复制了 C 中的函数参数。因此,在外部上下文中,nCheck = NULL,您将其传递给 CallIntAllocation 函数并进行复制。CallIntAllocation 将其本地副本 nCheck 定义为 malloc 调用的返回。但是外部副本没有更新——它仍然指向 NULL。

最简单的解决方案是返回新的指针值并按照几个人的建议进行分配。

当您有需要修改数据结构的函数时,您需要传递指向它们的指针,而不是它们的副本,以便函数可以修改指针指向的内容。同样的原则也适用于此,尽管您要修改的数据结构本身就是一个指针。

因此,另一种解决方案是 CallIntAllocation 采用指向指针的指针,它可以让您修改指针指向的位置,并取消引用它:

CallIntAllocation(int** nCheck, int nCount)
{

    *nCheck = (int*)malloc(nCount* sizeof(int));
    for (int j = 0; j < nCount; j++)
        (*nCheck)[j] = 0;
}

和调用

CallIntAllocation(&nCheck, nCount);

显然,在这种情况下,返回一个新的指针值是明智的做法。

最后一点:如果你有它可用,“memset”(C90 但不是 C89 afaik,但是单个 unix 规范的一部分)可以用来代替你的“for”循环

memset(ncheck, 0, nCount);

(这是针对您的函数版本,而不是采用 int ** 参数的版本)

于 2009-06-15T13:36:35.357 回答
0

您可以“返回”指向已分配内存的指针。如果返回 NULL,则表示分配不成功。

于 2009-06-15T08:08:31.573 回答