2010-04-08 72 views
2

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

这是一些示例代码(很简单):

... 
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; 
} 

这确实给我同样的地址之前和分配呼叫后:

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

我知道这可能是因为它使函数中的一个副本,但我不知道如何实际处理作为参数的指针。我尝试了定义some_struct *而不是some_struct,但没有运气。我试着用:

int allocate(some_struct **arg) 

它工作得很好(需以及改变分配功能),而是根据分配我可能不会改变的声明,它必须是* ARG。而这将是最正确的,如果我只需要声明some_struct s ..不是some_struct * s。 分配函数的目的是初始化一个struct(一个some_struct),它也包括分配它。

还有一件事我忘了提。分配函数中的返回0保留给一些状态消息,因此我不能使用这个返回地址。

+1

'allocate'函数的真正目的是什么? – Earlz 2010-04-08 15:50:30

+1

如果你必须传递一个'* some_struct',并在要分配的函数内分配内存,那么分配是不可能的。你能否发表更多的作业细节,大概你应该学习什么? – 2010-04-08 15:59:56

+0

哦,当你发布更多的细节时,这里要做的正确的事情就是编辑你的问题来包含它们。你在这里似乎是新手,可能不知道礼仪。 – 2010-04-08 16:14:16

回答

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*,并且没有丢失,但语言中没有任何内容保证some_struct*可以存储some_struct**而不会丢失。但它很有可能工作得很好。

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

+0

谢谢。这似乎工作,但代码不漂亮。是的,我觉得它也很奇怪。该函数也必须返回0,因为我忘了提及。 但我记得pthreads ..据他所知,他们的工作就像这样。 你初始化这样的一些属性: pthread_attr_t attr; pthread_attr_init(&attr); ,然后你用的是作为参数调用在pthread_create。 这init的分配pthread_attr_t结构。 – Casper 2010-04-08 16:34:17

+0

我有一种挥之不去的感觉,规范分配得到某处出现乱码,无论是在老师的结束或卡斯帕的我会认真仔细地检查一下这个任务的意图,然后再打开。 – 2010-04-08 19:21:55

+0

是的,我有点觉得我误解了任务..这个问题只是其中的一部分 是必须的是一个some_struct * arg参数,也许我应该从函数内部分配数据,但是函数没有目的。嗯..这很奇怪。 – Casper 2010-04-09 09:06:16

0

你不能这样做。你不能通过值声明一个结构体,然后通过地址来改变它。

+1

我有时希望'&foo = ...'是有效的语法。 :P – Earlz 2010-04-08 16:00:10

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; 
} 

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

+0

他指出他不允许这样做。 – 2010-04-08 15:55:09

+0

@Jason,那么这是不可能的。 – Earlz 2010-04-08 15:59:37

+0

@Earlz:我认为David有他的教授正在寻找的答案吗? – 2010-04-08 16:03:03

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); 
0

好,C采用传递的价值,这意味着函数获得副本的参数,并且对这些副本所做的任何更改都不会影响调用方中的原始副本。

/* 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没有改变。它仍然有任何它被初始化的随机数,你打印出来的。

如果您不能更改分配函数的签名,它永远不会有用。它必须接受一个指针的地址,以便它可以修改该指针的值,或者它必须返回一个指向你的调用者可以放开的指针。

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;