我有几个不同的功能,看起来像这样的代码:
void someFunction (int *data) {
data = (int *) malloc (sizeof (data));
}
void useData (int *data) {
printf ("%p", data);
}
int main () {
int *data = NULL;
someFunction (data);
useData (data);
return 0;
}
someFunction ()
和useData ()
是在单独的模块(* .c文件)中所定义。
问题是,虽然malloc的正常工作,而且分配的内存在使用someFunction
,一旦函数返回相同的内存不可用。
该程序的运行的例子可以看出这里 ,与输出,显示出不同的存储器地址。
可有人请向我解释什么,我做错了,我怎么能得到这个代码工作?
编辑:所以好像我需要用双指针来做到这一点-我怎么会去这样做同样的事情,当我真正需要使用双指针? 因此,如数据
int **data = NULL; //used for 2D array
我这时就需要在函数调用使用三重指针?
Answer 1:
你想用一个指针到指针:
void someFunction (int **data) {
*data = malloc (sizeof (int));
}
void useData (int *data) {
printf ("%p", data);
}
int main () {
int *data = NULL;
someFunction (&data);
useData (data);
return 0;
}
为什么? 那么,你想改变你的指针data
在主函数。 在C语言中,如果你想改变则传递作为参数的东西(和有变化呼叫者的版本显示出来),你必须在任何你想改变一个指针来传递。 在这种情况下,说:“你想改变的东西”是一个指针 - 这样一来就能改变这个指针,你必须使用一个指针到指针...
请注意,在主要问题的顶部,有一个在代码另一个bug: sizeof(data)
给你存储指针(所需要的字节数4个字节在32位操作系统上或在64位操作系统8个字节),而你真正想要的指针指向 (一个用于存储所需的字节数int
,即在大多数操作系统4个字节)。 因为一般sizeof(int *)>=sizeof(int)
,这可能不会造成问题,但它的东西要注意的。 我在上面的代码中纠正了这个。
这里是指针到指针一些有用的问题:
如何指针的指针工作用C?
配用指针引用的多层次?
Answer 2:
一个常见的错误,特别是如果你搬到形式的Java与C / C ++
记住,当你传递一个指针,它是按值传递即指针的值复制。 这是很好的就可以更改由指针所指向的数据,但指针本身的任何变化是因为它的一个副本只是地方!
诀窍是参照,因为你想改变它,即它的malloc等使用过的指针
**指针 - >会吓跑一个noobie C程序员)
Answer 3:
你必须传递指针的指针,如果你想修改指针。
即。 :
void someFunction (int **data) {
*data = malloc (sizeof (int)*ARRAY_SIZE);
}
编辑:新增ARRAY_SIZE,在某些时候你必须知道你要多少整数分配。
Answer 4:
这是因为指针数据是按值传递给someFunction
。
int *data = NULL;
//data is passed by value here.
someFunction (data);
//the memory allocated inside someFunction is not available.
指针的指针或返回分配指针可以解决这个问题。
void someFunction (int **data) {
*data = (int *) malloc (sizeof (data));
}
int* someFunction (int *data) {
data = (int *) malloc (sizeof (data));
return data;
}
Answer 5:
someFunction()将其参数作为INT *。 所以,当你从main()中,你通过创造的价值的一个副本调用它。 无论你是在函数内部修改是这个副本,因此更改不会外部的反射。 正如其他人的建议,你可以使用int **得到体现在数据的变化。 这样做的Otherway是从someFunction返回INT *()。
Answer 6:
除了用doublepointer技术,如果只有1回PARAM需要重写为如下:
int *someFunction () {
return (int *) malloc (sizeof (int *));
}
并使用它:
int *data = someFunction ();
Answer 7:
下面是一个函数分配内存,并通过参数返回指针的一般模式:
void myAllocator (T **p, size_t count)
{
*p = malloc(sizeof **p * count);
}
...
void foo(void)
{
T *p = NULL;
myAllocator(&p, 100);
...
}
另一种方法是使指针的函数的返回值(我的首选方法):
T *myAllocator (size_t count)
{
T *p = malloc(sizeof *p * count);
return p;
}
...
void foo(void)
{
T *p = myAllocator(100);
...
}
对内存管理的一些注意事项:
- 为了避免与内存管理的问题,最好的办法是避免内存管理技术。 不与动态内存淤泥,除非你真的需要它。
- 除非您使用的是早于1989年ANSI标准的实现,或者你打算编译代码为C ++不要投malloc()函数的结果。 如果你忘了包括stdlib.h中或以其他方式不具备的范围malloc()函数的原型,铸造返回值会剿了宝贵的编译器诊断。
- 使用被分配的物体的大小,而不是数据类型的大小(即,
sizeof *p
代替sizeof (T)
); 这将节省你一些灼热如果数据类型必须改变(比如从int长或浮动双)。 这也使得读好一点的IMO代码。 - 隔离后面更高级别的分配和释放功能的存储器管理功能; 这些不仅可以处理分配,但也初始化和错误。
Answer 8:
在这里,你正试图从“数据== NULL”修改该指针即“数据== 0xabcd”你分配一些其他的内存。 因此,要修改,你需要传递的数据即与数据的地址数据。
void someFunction (int **data) {
*data = (int *) malloc (sizeof (int));
}
Answer 9:
在回答你,你在编辑的另一个问题:
“*”表示指针的东西。 所以,“**”将是一个指针的指针的东西,“***”一个指向指针的指针的东西,等等。
“诠释**数据”(如果数据不是一个函数参数)的通常解释将是一个指针(“INT [100] [100]”例如)INT阵列的列表。
所以,你需要首先分配您的INT阵列(我用的()为简单起见,直接调用函数malloc):
data = (int**) malloc(arrayCount); //allocate a list of int pointers
for (int i = 0; i < arrayCount; i++) //assign a list of ints to each int pointer
data [i] = (int*) malloc(arrayElemCount);
Answer 10:
而不是使用双指针我们可以只分配一个新的指针,就回到它,因为它是不是在功能的任何地方使用无需通过双指针。
返回void *
等都可以用于任何类型的分配。
void *someFunction (size_t size) {
return malloc (size);
}
并把它作为:
int *data = someFunction (sizeof(int));
文章来源: How can I allocate memory and return it (via a pointer-parameter) to the calling function?