我如何分配内存,并(通过指针参数),它返回到调用函数?(How can I allocate mem

2019-07-17 11:17发布

我有几个不同的功能,看起来像这样的代码:

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

对内存管理的一些注意事项:

  1. 为了避免与内存管理的问题,最好的办法是避免内存管理技术。 不与动态内存淤泥,除非你真的需要它。
  2. 除非您使用的是早于1989年ANSI标准的实现,或者你打算编译代码为C ++不要投malloc()函数的结果。 如果你忘了包括stdlib.h中或以其他方式不具备的范围malloc()函数的原型,铸造返回值会剿了宝贵的编译器诊断。
  3. 使用被分配的物体的大小,而不是数据类型的大小(即, sizeof *p代替sizeof (T) ); 这将节省你一些灼热如果数据类型必须改变(比如从int长或浮动双)。 这也使得读好一点的IMO代码。
  4. 隔离后面更高级别的分配和释放功能的存储器管理功能; 这些不仅可以处理分配,但也初始化和错误。


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?