代码之家  ›  专栏  ›  技术社区  ›  Sunscreen

通过函数(ansi c c)分配数据

  •  1
  • Sunscreen  · 技术社区  · 16 年前

    我想知道如何通过函数分配数据,在函数返回后,数据仍然被分配。这既适用于基本类型(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));
    
    
        }
    
    }
    

    有什么想法吗?我想我需要传递指针作为参考,但我怎么做呢?

    事先谢谢, 防晒霜

    5 回复  |  直到 10 年前
        1
  •  2
  •   jmtd    16 年前

    它不工作的原因是C中的函数参数被复制。因此,在外部上下文中,check=null,将其传递到callintallocation函数中,并生成一个副本。Callintallocation定义它是 地方的 要返回malloc调用的check副本。但是外部副本没有更新——它仍然指向空值。

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

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

    所以另一个解决方案是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**参数的版本)

        2
  •  5
  •   dfa    16 年前

    使用回报?

    Criteria *
    newCriteria() {
       Criteria *criteria = malloc(..);
       ...
       return criteria;
    }
    
    /* the caller */
    Criteria *c1 = newCriteria();
    Criteria *c2 = newCriteria();
    

    编辑

    呼叫方负责呼叫free()。

        3
  •  4
  •   Valerii Hiora    16 年前

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

     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); 
    
        4
  •  3
  •   Graeme Perrow    16 年前

    要直接回答您的问题:

    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;
    }
    
        5
  •  0
  •   Aditya Sehgal    16 年前

    您可以将指针“返回”到分配的内存。如果返回空值,则表示分配失败。