在以下示例中,函数func()
将本地指针变量的地址返回到main()
函数。它在海湾合作委员会中运作良好。
那么,这是明确定义的行为吗?
#include <stdio.h>
#include <stdlib.h>
int *func(void);
int *func(void)
{
int *p;
p = malloc(sizeof *p);
*p = 10;
return p;
}
int main()
{
int *ptr = func();
printf("%d\n",*ptr);
return 0;
}
答案 0 :(得分:9)
不,你做不返回一个指向本地变量(的地址)的指针。这将是类似
的事情int i = 10;
return &i;
而是返回指向堆上分配的对象的指针。
你确实有内存泄漏,因为你不会在任何地方free
内存。调用free
应该通过代码调用你的函数来完成(除非它依次返回指针 value ,其中责任继续在他调用链上)。
答案 1 :(得分:3)
在func()
内,p
是指向由malloc()
分配的内存的指针(或可能分配的内存,因为malloc()
可能会失败,返回空指针;这应该检查)。如果成功,此内存分配将持续存在,直到明确free
d。
在这种情况下,p
的值将返回给调用函数main()
。 p
是指向成功分配的指针,或者是空指针,然后将返回的值(临时值,而不是左值)分配给ptr
。因此,分配的存储可以通过ptr
访问,p
是func()
在p
返回之前所拥有的值的副本,但func()
的生命周期为{{ 1}}现在已经结束,ptr
已经返回。
当不再需要时,free
应该malloc()
以避免内存泄漏。并且,如果ptr
失败,则此处存在潜在的未定义行为,因为>>> job = group([
... add.subtask((2, 2)),
... add.subtask((4, 4)),
... add.subtask((8, 8)),
... add.subtask((16, 16)),
... add.subtask((32, 32)),
... ])
>>> result = job.apply_async()
>>> result.join()
[4, 8, 16, 32, 64]
是空指针。
答案 2 :(得分:1)
这完全有效。
不保证的是,一旦函数返回并且堆栈帧缩小,堆栈帧上的变量会发生什么。
您要返回的是某个strdup()
内存的地址,而不是本地变量的地址(在堆栈上分配)。这与strdup()
的工作方式非常相似。以下是char *
strdup(str)
const char *str;
{
size_t len;
char *copy;
len = strlen(str) + 1;
if (!(copy = malloc((u_int)len)))
return (NULL);
bcopy(str, copy, len);
return (copy);
}
的{{1}}实现。
free
一个明显的缺点(正如“一些程序员家伙”所提到的)是<?php
$test = array();
$test2[] = array(
'key1' => '111',
'key2' => '111',
'key3' => '111',
);
$test2[] = array(
'key1' => '222',
'key2' => '222',
'key3' => '222',
);
$test['tax_query'] = array(
'relation' => 'AND',
$test2,
);
print_r($test);
?>
的责任传递给调用者。
答案 3 :(得分:1)
这是一个有效且正确的代码,虽然有点令人困惑。
func正在分配大小为int的内存。通过取消引用int类型的指针变量来完成分配。
更改分配在内存中设置整数值10。 10应该设置为整数(可以依赖于编译器)。但绝对不会大于整数的大小,所以应该是安全的操作。
之后,函数返回指针值。
在main()中,返回的指针被设置为另一个整数指针。这指向malloc()分配的原始内存。
之后,在printf()语句中打印取消引用的整数指针。这将打印10的值。
缺少的是free()调用,这不是这里的好行为。
这对孩子们来说是一次很好的学术练习。