【问题标题】:why pointer to pointer is needed to allocate memory in function为什么需要指向指针的指针来在函数中分配内存
【发布时间】:2010-07-01 22:42:45
【问题描述】:

我在下面的代码中出现了分段错误,但是在我将其更改为指向指针的指针后,它就可以了。谁能给我任何理由?

void memory(int * p, int size) {
    try {
        p = (int *) malloc(size*sizeof(int));
    } catch( exception& e) {
        cout<<e.what()<<endl;   
    }
}

它在主函数中不起作用

int *p = 0;
memory(p, 10);

for(int i = 0 ; i < 10; i++)
    p[i] = i;

但是,它的工作原理是这样的。

void memory(int ** p, int size) {               `//pointer to pointer`
    try{
        *p = (int *)    malloc(size*sizeof(int));
    } catch( exception& e) {
        cout<<e.what()<<endl;   
    }
}

int main()
{
    int *p = 0;
    memory(&p, 10);       //get the address of the pointer

    for(int i = 0 ; i < 10; i++)
        p[i] = i;

    for(int i = 0 ; i < 10; i++)
        cout<<*(p+i)<<"  ";

    return 0;
}

【问题讨论】:

  • 因为 malloc 永远不会抛出,那些 try 块毫无意义。
  • 如果这是 C,那些 try 块是无效的。这实际上是 C++ 吗?如果是这样,标签需要更改。
  • @Pavel:是的,但没用 ;-)
  • @Pavel 很好,如果你想动态分配一个你会使用的指针数组
  • 要么问题是关于 C,在这种情况下 try 块是错误的,要么是关于 C++,在这种情况下它不应该使用 malloc()

标签: c++ memory-management malloc


【解决方案1】:

因为您想从函数中完成的操作中获取指针值backmalloc 分配内存并为您提供该内存的地址。

在您的第一个示例中,您将该地址存储在本地参数变量 p 中,但由于它只是参数,因此不会将其返回到主程序,因为 C/C++ 是 pass-默认情况下按值 - 即使是指针。

Main      Function      malloc

  p         p            allocated
+---+     +---+         
| 0 |     | 0 |           A
+---+     +---+

becomes...

  p         p            allocated
+---+     +---+         
| 0 |     | ------------> A
+---+     +---+

因此当 main 读取 p 时,它得到 0,而不是 A。

在您的工作代码中,您遵循传递给地址的指针,该地址为您提供了主程序中指针变量的位置。您更新该地址处的指针值,然后主程序可以查找该值以用作其内存位置 - 从而将 malloc 返回的地址传递回主程序以供使用。

Main      Function      malloc

  p         p            allocated    
+---+     +---+         
| 0 |<------- |           A
|   |     |   |
+---+     +---+

becomes...

  p         p            allocated    
+---+     +---+         
|   |<------- |           
| ----------------------> A
+---+     +---+

因此当 main 读取 p 时,它会得到 A。

【讨论】:

  • 该死...我本来打算制作漂亮的指针图...不再是了
【解决方案2】:

指针存储数据的存储地址。将指针传递给函数意味着给它数据的地址。但是,在调用malloc 之前,这里没有数据地址。因此,您需要传递 指针 的地址(即指向指针的指针)。这允许memory 获取指针p 的地址并将p 设置为指向它为数据分配的内存区域。

【讨论】:

  • 比 Dav 的要清楚得多,尽管看起来你们俩说的是同一件事。你们都得到了赞成票。 :)
【解决方案3】:

在 C 中,您只有值传递。所以你的函数 memory() 得到它自己的 p 的本地副本。 memory() 中的 malloc 只分配给函数本地的 p 副本。 当 memory() 返回 main() 时,来自 main 的 p 副本保持不变。在 C++ 中,您可以使用 pass-by-reference 来解决这个问题,如下所示:

void memory(int*&amp; p, int size)

在 C 中,您使用双指针来实现类似的结果。

【讨论】:

  • 应该是*&amp;。 (从右边阅读。这是我将空格放在另一个方向的原因之一:int*&amp; pint* 是您要引用的类型):)
  • 难道不是int *&amp; 来表示对指向 int 的指针的引用吗?您的代码示例是 int &amp;*,它是一个指向 int 引用的指针,如果您传递一个指向引用的指针,它就违背了引用的目的。还是我看错了……?
  • @UncleBens,Dustin:这是一个错字,不错。我也将空格 &* 移到了类型旁边。
【解决方案4】:

在你的第一次回忆中:

void memory(int * p, int size)

意识到您正在将 VALUE 传递给 memory(),而不是地址。因此,您将“0”的值传递给 memory()。变量p 只是您传入的任何内容的副本... in 包含相同的值,但 NOT 是否指向相同的地址...

在您的第二个函数中,您传递了参数的 ADDRESS...所以,p 指向变量的地址,而不仅仅是变量的副本。

所以,当你像这样调用 malloc 时:

*p = (int *)    malloc(size*sizeof(int));

您将 malloc 的返回值分配给 p 指向的变量的值。

因此,您的指针在 memory() 之外有效。

【讨论】:

    【解决方案5】:

    第一个例子不起作用,因为指针参数不是main中的指针,它只是保持相同的值。

    【讨论】:

      【解决方案6】:

      您不需要使用指向指针的指针,而是使用引用的指针,即 * & 而不仅仅是 *

      【讨论】:

        【解决方案7】:

        您需要一个指向指针的指针,因为您需要返回新分配的指针的值。

        有三种方法可以返回该值(如果使用 C,则为 2):

        • 使用指针,这里是指向指针的指针
        • 使用引用,这里是对指针的引用
        • 使用函数的返回值,所以让内存返回一个int *而不是void

        第三种方式绝对是我的偏好。

        (不是,我不承认你也可以使用全局,这不是第四种方式,而是一种恐怖)。

        【讨论】:

          【解决方案8】:

          内存(p, 10); //获取指针地址

          这只是发送 p 值而不是 p 的地址。它发送 (*p)。如果 p 的地址为 123,其值为 50,则将 50 发送给函数。

          并在内存函数中创建一个新指针,新地址为 124,包含 50;它将分配内存并将分配内存的开头写入 124 而不是 123,所以主要的 p 仍然包含 50。所以你什么也没做!您可以使用此代码进行控制。

               #include<iostream>
              #include<conio.h>
              #include<exception>
          
              using namespace std;
          
          
              void memory(int* p, int size) {               //*************pointer to pointer` is a must**********
                  try{
                      p = new int[size] ;
                      p[0]=100;
                  } catch(bad_alloc &e) {
                     cout<<e.what()<<endl;   
                  }
              }
          
              int main()
              {
                   int *p = 0;  ******you can do you should do this*******
                  p = new int ; 
          /* p = malloc( sizeof(int)); // this just change the value inside of p it is unnecessary 
          and you will lose a adress from memory :) and possibly it will be unsafe if you free p may, you just 
          free one adress*/
                  /*before using a pointer always allocate it memory else
                   you ll get frequent system crashes and BSODs*/
                  memory(p, 10);       //get the address of the pointer//you are getting nothing
                  cout <<p[0];
                  //we set p[0] to 100 but it will write a garbage value here. 
                  //because the value inside of p didn't change at the memory function
                  //we sent just the value inside of p.
          
                  getch();    
                  return 0;
              }
          

          【讨论】:

            【解决方案9】:

            我更正了代码..阅读评论,一切都会清楚..

            #include<iostream>
            #include<conio.h>
            #include<exception>
            
            using namespace std;
            
            
            void memory(int* p, int size) {               //pointer to pointer` not needed
                try{
                    p = new int[size] ;
                } catch(bad_alloc &e) {
                   cout<<e.what()<<endl;   
                }
            }
            
            int main()
            {
                // int *p = 0;  wrong .. no memory assigned and then u are passing it to a function
                int *p;
                p = new int ;  // p = malloc( sizeof(int));
                /*before using a pointer always allocate it memory else
                 you ll get frequent system crashes and BSODs*/
                memory(p, 10);       //get the address of the pointer
            
                for(int i = 0 ; i < 10; i++)
                    p[i] = i;
            
                for(int i = 0 ; i < 10; i++)
                    cout<<*(p+i)<<"  ";
            
                getch();    
                return 0;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-01-26
              • 1970-01-01
              • 1970-01-01
              • 2018-05-16
              • 1970-01-01
              • 2010-10-28
              相关资源
              最近更新 更多