通过函数分配数据 (ANSI C)
我很想知道如何通过函数分配数据,并且在函数返回后数据仍然被分配。 这适用于基本类型(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));
}
}
有什么想法吗? 我想我需要传递指针作为参考,但我该怎么做呢?
提前致谢, 防晒霜
I d love to know how I can allocate data through a function, and after the function is returned the data is still allocated. This is both for basic types (int, char**) and user defined types. Below are two snipsets of code. Both have the allocation within the function though after the return the allocation goes.
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;
}
The same behaviour for as before though for user defined type:
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));
}
}
Any ideas? I think I need to pass the pointers as a reference, though how can i do so?
Thanks in advance,
Sunscreen
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用返回?
编辑
调用者负责调用 free()
using return?
EDIT
the caller is responsible for calling free()
您有 2 种可能的解决方案:
或者如果您想分配数组,您应该传递一个指向 int* 的指针:
You have 2 possible solutions:
or you should pass a pointer to int* if you want to alloc array:
直接回答你的问题:
但我建议这样做:
To answer your question directly:
but I would suggest this in stead:
它不起作用的原因是 C 中的函数参数被复制。 因此,在外部上下文中,nCheck = NULL,将其传递到 CallIntAllocation 函数中并创建副本。 CallIntAllocation 将其 nCheck 的本地副本定义为 malloc 调用的返回。 但外部副本没有更新——它仍然指向 NULL。
最简单的解决方案是返回新的指针值并按照几个人已经建议的方式对其进行分配。
当您有需要修改数据结构的函数时,您需要向它们传递一个指针,而不是它们的副本,以便函数可以修改指针指向的内容。 同样的原理也适用于此,尽管您要修改的数据结构本身就是一个指针。
因此,另一个解决方案是 CallIntAllocation 采用指向指针的指针,这将允许您修改指针指向的位置,并取消引用它:
并且调用
显然在这种情况下返回新的指针值是明智的方法。
最后一点:如果你有它可用,“memset”(C90,但不是 C89 afaik,但是单一 unix 规范的一部分)可以用来代替你的“for”循环
(这是你的函数版本,而不是那个版本)需要一个 int ** 参数)
The reason it is not working is that function arguments in C are copied. So, nCheck = NULL in the outside context, you pass it into the CallIntAllocation function and a copy is made. The CallIntAllocation defines it's local copy of nCheck to be the return of the malloc call. But the outer copy is not updated -- it still points at NULL.
The simplest solution is to return the new pointer value and assign it as already suggested by several people.
When you have functions that need to modify data structures, you need to pass around a pointer to them, rather than copies of them, so that the function can modify what the pointer points at. The same principle applies here, although the data structure you want to modify is itself a pointer.
So another solution would be for CallIntAllocation to take a pointer-to-a-pointer which would let you modify where the pointer points, and also dereference it:
and invocation
Clearly in this situation returning a new pointer value is the sensible approach.
Final point: if you have it available, "memset" (C90 but not C89 afaik, part of the single unix specification however) can be used in place of your "for" loop
(that's for your version of the function, not the one that takes an int ** argument)
您可以将指针“返回”到已分配的内存。 如果返回NULL,则表示分配不成功。
You can "return" the pointer to the allocated memory. If NULL is returned, that means the allocation was unsuccessful.