代码之家  ›  专栏  ›  技术社区  ›  a_m0d

如何分配内存并(通过指针参数)将其返回给调用函数?

  •  29
  • a_m0d  · 技术社区  · 15 年前

    我在两个不同的函数中有一些代码,看起来像这样:

    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文件)中定义。

    someFunction ,函数返回后,相同的内存将不可用。

    here ,输出显示各种内存地址。

    有人能解释一下我在这里做错了什么,以及我如何让这个代码工作吗?


    双指针?例如,数据是

    int **data = NULL; //used for 2D array
    

    那么我是否需要在函数调用中使用三重指针?

    10 回复  |  直到 15 年前
        1
  •  75
  •   Community c0D3l0g1c    7 年前

    要使用指向指针的指针:

    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) (一) int ,即大多数操作系统上的4个字节)。因为通常 sizeof(int *)>=sizeof(int) ,这可能不会造成问题,但这是需要注意的。我已经在上面的代码中更正了这一点。

    以下是一些关于指针指向指针的有用问题:

    How do pointer to pointers work in C?

    Uses for multiple levels of pointer dereferences?

        2
  •  9
  •   Sid Sarasvati    12 年前

    诀窍是使用通过引用传递指针,因为你想改变它,比如malloc等等。

    **指针-->会吓到noobie C程序员;)

        3
  •  4
  •   Ben    15 年前

    如果要修改指针,必须将指针传递给该指针。

    即:

    void someFunction (int **data) {
      *data = malloc (sizeof (int)*ARRAY_SIZE);
    }
    

    编辑:

        4
  •  2
  •   aJ.    15 年前

    这是因为指针数据是按值传递给 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;
    }
    
        5
  •  2
  •   Naveen    15 年前

    someFunction()将其参数设置为int*。因此,当您从main()调用它时,将创建您传递的值的副本。无论您在函数内部修改什么,都是此副本,因此更改不会反映在函数外部。正如其他人所建议的,您可以使用int**来获得反映在数据中的更改。另一种方法是从someFunction()返回int*。

        6
  •  2
  •   Toad    15 年前

    除了使用双指针技术外,如果只需要1个返回参数,则重写如下:

     int *someFunction () {
       return (int *) malloc (sizeof (int *));
     }
    

     int *data = someFunction ();
    
        7
  •  1
  •   John Bode    15 年前

    以下是在函数中分配内存并通过参数返回指针的一般模式:

    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. sizeof *p 而不是 sizeof (T) ); 如果数据类型必须更改(例如从int更改为long或从float更改为double),这将为您节省一些麻烦。这也使代码在IMO中读得更好一些。
    3. 将内存管理功能隔离在更高级别的分配和取消分配功能之后;它们不仅可以处理分配,还可以处理初始化和错误。
        8
  •  0
  •   Learner    15 年前

    在这里,您试图修改指针,即从“data==Null”到“data==0xabcd”您分配的其他一些内存。因此,要修改需要传递数据地址的数据,即&数据

    void someFunction (int **data) {
      *data = (int *) malloc (sizeof (int));
    }
    
        9
  •  0
  •   Razzupaltuff    15 年前

    答复您在中编辑的其他问题:

    “int**data”(如果数据不是函数参数)的通常解释是指向int数组列表的指针(例如“int a[100][100])。

    因此,您需要首先分配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);
    
        10
  •  0
  •   Delimitry COLD TOLD    8 年前

    回来 void *

    void *someFunction (size_t size) {
        return  malloc (size);
    }
    

    并将其用作:

    int *data = someFunction (sizeof(int));
    
        11
  •  0
  •   Deadwood Kumu    5 年前

    为了简单起见,让我调用上面的单指针参数p

    在一个函数中,p指向的对象可以改变,并且改变会消失 功能。但是,如果p本身发生了变化,则变化不会发生 离开函数。

    不幸的是,malloc本身的特性 校正(58)使用指向p的指针pp。以正确的方式 函数,p已更改,但pp未更改。它就这样起作用了。