首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过函数分配数据(ANSI C)

通过函数分配数据(ANSI C)
EN

Stack Overflow用户
提问于 2009-06-15 07:53:44
回答 5查看 868关注 0票数 1

我想知道如何通过函数分配数据,并且在函数返回后,数据仍然是分配的。这既适用于基本类型(int、char**),也适用于用户定义类型。下面是两个代码片段集。两者在函数中都有分配,但在返回之后分配就会发生。

代码语言:javascript
运行
复制
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;
}

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

代码语言:javascript
运行
复制
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));


    }

}

有什么想法吗?我想我需要把指针作为一个引用来传递,但是我该怎么做呢?

提前谢谢你,防晒霜

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-06-15 13:36:35

它不工作的原因是C中的函数参数被复制了。因此,在外部上下文中,nCheck = NULL,您将其传递给CallIntAllocation函数并创建一个副本。CallIntAllocation将其nCheck的本地副本定义为malloc调用的返回值。但是外部副本不会更新--它仍然指向NULL。

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

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

因此,另一种解决方案是CallIntAllocation将指针指向指针,这将允许您修改指针指向的位置,并取消对其的引用:

代码语言:javascript
运行
复制
CallIntAllocation(int** nCheck, int nCount)
{

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

和调用

代码语言:javascript
运行
复制
CallIntAllocation(&nCheck, nCount);

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

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

代码语言:javascript
运行
复制
memset(ncheck, 0, nCount);

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

票数 2
EN

Stack Overflow用户

发布于 2009-06-15 08:01:10

使用return?

代码语言:javascript
运行
复制
Criteria *
newCriteria() {
   Criteria *criteria = malloc(..);
   ...
   return criteria;
}

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

编辑

调用者负责调用free()

票数 5
EN

Stack Overflow用户

发布于 2009-06-15 08:19:20

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

代码语言:javascript
运行
复制
 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*传递一个指针:

代码语言:javascript
运行
复制
 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); 
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/994938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档