【问题标题】:The usage of pointer star in CC中指针星的用法
【发布时间】:2012-05-03 21:10:42
【问题描述】:

我问了这个问题:Pass array by reference using C。我意识到我的问题是 C 中指针星的使用。最终结果证明,这种方法适用于我的程序:

#include <stdio.h>

void FillArray(int** myArray)
{   
     *myArray = (int*) malloc(sizeof(int) * 2);

     (*myArray)[0] = 1;
     (*myArray)[1] = 2;
}

int main()
{
     int* myArray = NULL;
     FillArray(& myArray);  
     printf("%d", myArray[0]);
     return 0;
}

到目前为止一切都很好。然后,我修改了 FillArray() 函数,如下所示,以获得更好的代码可读性:

#include <stdio.h>

void FillArray(int** myArray)
{
     int* temp = (*myArray);

     temp = (int*) malloc(sizeof(int) * 2);
     temp[0] = 1;
     temp[1] = 2;
}

int main()
{
     int* myArray = NULL;
     FillArray(& myArray);  
     printf("%d", myArray[0]);
     return 0;
}

现在,我在 printf 行收到以下运行时错误:

Trial.exe 中 0x773115de 处未处理的异常:0xC0000005:访问冲突读取位置 0x00000000。

尽管我不是 C 专家,但进行这种修改似乎是合法的。但是,显然它不起作用。语法是不是有点混乱?我错过了什么吗?

感谢您的有用回答,

坐下。

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    temp 得到了myArray 的地址的副本,但随后你将一些malloced 内存分配给temp,所以原来的分配毫无意义,也没有持久的效果。然后修改malloced 内存,但这根本不会改变myArray。要在main 中更改myArray,您必须分配

    *myArray = temp;
    

    FillArray 结尾。

    void FillArray(int** myArray)
    {
         int* temp;
         temp = (int*) malloc(sizeof(int) * 2);
         temp[0] = 1;
         temp[1] = 2;
         *myArray = temp;
    }
    

    做你想做的。

    【讨论】:

    • @DanielFischer temp 实际上没有得到任何东西 (*myArray) 在第一行会引发访问破坏,因为 myArray 是 NULL 并且不能被取消引用
    • @Abid 不,他调用FillArray(&amp; myArray);,事实上main 中的myArray 与函数参数同名这一事实令人困惑。在FillArray 中,*myArrayNULLmain 中的myArray 是什么。
    • @DanielFischer 哦!!我看错了。我虽然他是通过一个 ** 。谢谢
    【解决方案2】:

    您将 malloc 的缓冲区分配给堆栈上的一个局部变量,然后在您返回时泄漏该内存。您永远不会影响传递给函数的指针。

    【讨论】:

    • 感谢您的回答。是的,您检测到了问题。
    【解决方案3】:
    int* temp = (*myArray);
    

    temp 是一个局部变量。对其进行的任何修改都不会影响原件。

    temp = (int*) malloc(sizeof(int) * 2);  // Will not affect *myArray
    

    或多或少有点像-

    void foo( int * ptr )
    {
       ptr = malloc( sizeof(int) );
    }
    
    int *a ;
    foo(a);   // Does `a` get allocated too ? NO.
    

    【讨论】:

      【解决方案4】:

      这对我有用:

      #include <stdio.h>
      
      void FillArray(int** myArray)
      {
          (*myArray) = (int*) malloc(sizeof(int) * 2);
          (*myArray)[0] = 1;
          (*myArray)[1] = 2;
      }
      
      int main()
      {
          int* myArray = NULL;
          FillArray(& myArray);  
          printf("%d\n", myArray[0]);
          printf("%d\n", myArray[1]);
          return 0;
      }
      

      【讨论】:

        【解决方案5】:
        int* temp = (*myArray);
        

        这一行是问题的根源,让我们看看这行是什么。

        它表示取消引用myArray 并将结果值分配给temp,这是一个int *,并且由于myArray 是和int **,取消引用将导致int *。但是您不能取消引用未指向任何位置的指针,因为当您将 myArray 作为参数传递时,它是 NULL 并且当您执行 (*myArray) 时,它会尝试访问 myArray 指向的内存位置(这是 no-where因为 myArray 为 NULL)因此访问冲突读取位置 0x00000000,这意味着您正在尝试取消引用 NULL 指针。

        除了上述之外,让我们看看您的代码在做什么 一开始的画面是这样的

        myArray ======> NULL
        

        第一行之后

        int* temp = (*myArray); //pointing temp to (*myArray)
        

        因为 myArray 是 NULL temp points no where 所以新图片

        myArray =======> NULL
        temp =======> NULL
        

        第 2 行 temp = (int*) malloc(sizeof(int) * 2);

        分配两个整数的内存并将新分配的内存指向temp,这样图片就变成了

        myArray =======> NULL
        temp =======> [ ] [ ]
        

        下两行将 1 和 2 存储在 temp 指向的第一和第二内存位置

         temp[0] = 1;
         temp[1] = 2;
        

        所以现在图片是

        myArray =======> NULL
        temp =======> [1] [2]
        

        【讨论】:

          【解决方案6】:

          分配前的Malloc temp!

          【讨论】:

            猜你喜欢
            • 2011-07-25
            • 2011-01-06
            • 2011-04-01
            • 1970-01-01
            • 2010-11-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多