我想知道如何通过函数分配数据,并在返回函数后仍然分配数据。这适用于基本类型(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));
}
}
有什么想法吗?我想我需要传递指针作为参考,虽然我怎么能这样做?
提前致谢, 防晒
答案 0 :(得分:5)
使用return?
Criteria *
newCriteria() {
Criteria *criteria = malloc(..);
...
return criteria;
}
/* the caller */
Criteria *c1 = newCriteria();
Criteria *c2 = newCriteria();
修改强>
调用者负责调用free()
答案 1 :(得分:4)
您有两种可能的解决方案:
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);
答案 2 :(得分: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;
}
答案 3 :(得分:2)
它不起作用的原因是C中的函数参数被复制。因此,在外部上下文中nCheck = NULL,您将其传递给CallIntAllocation函数并进行复制。 CallIntAllocation将nCheck的 local 副本定义为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 **参数的版本)
答案 4 :(得分:0)
您可以“返回”指向已分配内存的指针。如果返回NULL,则表示分配失败。