Malloc里面的另一个功能

时间:2010-04-08 15:47:21

标签: c malloc allocation c89

我必须从另一个函数中分配一个结构,显然是使用指针。 我一直盯着这个问题好几个小时,并尝试了一百万种不同的方法来解决它。

这是一些示例代码(非常简化):

...
some_struct s;
printf("Before: %d\n", &s);
allocate(&s);
printf("After: %d\n", &s);
...

/* The allocation function */
int allocate(some_struct *arg) {

arg = malloc(sizeof(some_struct));
printf("In function: %d\n", &arg);

return 0;
}

这确实给了我在allocate-call之前和之后的相同地址:

Before: -1079752900
In function: -1079752928
After: -1079752900

我知道这可能是因为它在函数中复制,但我不知道如何实际处理我给出的指针作为参数。我尝试定义some_struct * s而不是some_struct,但没有运气。我尝试过:

int allocate(some_struct **arg)

工作正常(分配函数也需要更改),但根据作业我可能不会更改声明,而且它必须是* arg ..如果我只是它是最正确的必须声明some_struct s ..不是some_struct * s。 分配函数的目的是初始化一个struct(some_struct),它还包括分配它。

我还忘了提一件事。分配函数中的返回0保留用于某些状态消息,因此我无法使用此返回地址。

6 个答案:

答案 0 :(得分:4)

通常,我会从allocate

返回指针
void * allocate()
{
    void * retval = malloc(sizeof(some_struct));
    /* initialize *retval */
    return retval;
}

如果要在参数中返回它,则必须传递指向参数的指针。由于这是指向some_struct的指针,因此必须将指针传递给指针:

void allocate (some_struct ** ret)
{
    *ret = malloc(sizeof(some_struct));
    /* initialization of **ret */
    return;
}

被称为

some_struct *s;
allocate(&s);

答案 1 :(得分:1)

int func(some_struct *arg) {
    arg = malloc(sizeof(some_struct));
    ... 
}

在这里,您只需将malloc的结果分配给本地arg变量。指针在C中传递值,指针的副本传递给函数。您不能以这种方式更改调用者的指针。请记住指针的差异及其指向的内容。

您有多种选择:

从函数返回指针:

 some_struct *func(void) {
    arg = malloc(sizeof(some_struct));
    ...
    return arg;
}
...
some_struct *a = func();

在调用方中分配结构:

 int func(some_struct *arg) {
    ...
    arg->something = foo;

}
... 
some_struct a;
func(&a);

或动态分配

some_struct *a = malloc(sizeof *a);
func(a);

使用指向调用者指针的指针:

 int func(some_struct **arg) {
    *arg = malloc(sizeof **arg);

}
... 
some_struct *a;
func(&a);

使用全局变量(丑陋......)

 some_struct *global;
 int func(void) {
    global = malloc(sizeof *global);

}
 ... 
some_struct *a;
func();
a = global;

答案 2 :(得分:1)

我非常怀疑这是您老师的想法,但您可以使用一系列合法类型的转换作弊。

   int allocate(some_struct *arg) 
   /* we're actually going to pass in a some_struct ** instead. 
      Our caller knows this, and allocate knows this.  */
   { 
      void *intermediate = arg;  /* strip away type information */
      some_struct **real_deal = intermediate;  /* the real type */
      *real_deal = malloc(sizeof *real_deal); /* store malloc's return in the 
                                                 object pointed to by real_deal */
      return *real_deal != 0;  /* return something more useful than always 0 */
   }

然后你的来电者也会这样做:

   {
      some_struct *s; 
      void *address_of_s = &s; 
      int success = allocate(address_of_s); 
      /* what malloc returned should now be what s points to */
      /* check whether success is non-zero before trying to use it */
   }

这依赖于C中的规则,该规则表明任何指向对象的指针都可以隐式转换为void指针,反之亦然,而不会丢失。

请注意,正式情况下这是未定义的,但它确实可行。虽然任何对象指针值都需要能够转换为void*而不会丢失,但语言中没有任何内容可以保证some_struct*可以保存some_struct**而不会丢失。但是很有可能工作得很好。

你的老师别无选择,只能写正式的非法代码。除了像这样“作弊”之外,我没有看到你有任何其他选择。

答案 3 :(得分:0)

你不能这样做。您不能按值声明结构,然后按地址更改它。

答案 4 :(得分:0)

some_struct *s;
printf("Before: %d\n", s");
allocate(&s);
printf("After: %d\n", s");
...

/* The allocation function */
int allocate(some_struct **arg) {

*arg = malloc(sizeof(some_struct));
printf("In function: %d\n", *arg");

return 0;
}

您需要修改结构的指向值。因此,您需要另一级别的间接,因此您必须发送指向结构指针的指针。

答案 5 :(得分:0)

嗯,C使用pass-by-value,这意味着函数会获取其参数的副本,对这些副本所做的任何更改都不会影响调用者中的原始文件。

/* The allocation function */
int allocate(some_struct *arg) {

arg = malloc(sizeof(some_struct));
printf("In function: %d\n", &arg");

return 0;
}

在这里传递some_struct的地址。然后丢弃该地址,并将其替换为malloc返回的内容。然后你返回,malloc的返回值永远丢失,你已经泄露了内存。并且你的some_struct没有改变。它仍然有你初始化的随机数,你打印出来的。

如果您不能更改分配功能的签名,则它永远不会有用。它必须获取指针的地址,以便它可以修改该指针的值,或者它必须返回一个指针,调用者可以丢弃它。

相关问题