【问题标题】:Calling Malloc using wrapper function使用包装函数调用 Malloc
【发布时间】:2013-11-29 09:20:27
【问题描述】:

我帮助在初学者课程中教授 C。我们正在讨论使用 malloc 进行动态内存分配,一个学生想在 malloc 周围放置一个包装器。我不确定这是否有用,但玩弄东西是最好的学习方式。

但是,当学生尝试通过他们的 malloc 包装函数为数组分配内存时,它不起作用 - 分段错误。

下面给出了一个最小的例子。

#include <stdlib.h> 

void mallocWrapper(int *intArray, int length){

    intArray = malloc(length * sizeof(int));
}

int main() { 

    int *array;
    int arraySize = 10;

    mallocWrapper(array, arraySize);

    // this line causes the Segmentation fault  
    array[0] = 0;

    return 0; 
} 

据我所知,数组变量将成为内存中为数组保留的第一个点的地址。我认为无论在哪里分配内存,即在 main 中还是在 mallocWrapper 中,都会出现这种情况。

因此,我不知道该告诉学生什么,只能回复他们。

任何帮助将不胜感激。谢谢

【问题讨论】:

  • 是的,我只是错过了它。我明白为什么它不起作用,现在将告诉提出问题的学生。但也许你从来没有错过你生活中的一个明显错误。在这种情况下,对你来说,调试一定是一个梦想。

标签: c arrays memory malloc


【解决方案1】:

如果你想改变调用者的array 成员,你需要传递一个指向它的指针。即,您需要将指向指针的指针传递给mallocWrapper

void mallocWrapper(int **intArray, int length){
    *intArray = malloc(length * sizeof(int));
}

mallocWrapper(&array, arraySize);

或者,更好的是,您可以更改 mallocWrapper 以返回新分配的内存。

void* mallocWrapper(int length){
    return malloc(length * sizeof(int));
}

array = mallocWrapper(arraySize);

【讨论】:

  • 第二种方法是要走的路。包装malloc() 并更改调用“样式”似乎非常不友好。
  • 当然——我应该发现...我的想法是指针通过引用传递并忘记了在这里我想更改实际的指针地址,而不是那个地址中的内容。谢谢回复。我同意第二种方法是最好的,因为它与其他帖子中提到的 malloc“风格”保持一致。
【解决方案2】:

您将指针array副本 传递给函数,因此函数内部的任何修改都不会反映在外部。您需要将函数的签名更改为void mallocWrapper(int **intArray, int length) 并使用*intArray = ..... 才能使其工作。

【讨论】:

    【解决方案3】:

    像这样使用:

    void mallocWrapper(int **intArray, int length)
    {
        *intArray = malloc(length * sizeof(int));
    }
    
    int main()
    {
    
        int *array    = NULL;    //Whenever you declare a pointer assign it to NULL
        int arraySize = 10;
    
        mallocWrapper(&array, arraySize);
    
        array[0] = 0;
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      在 C 中,函数参数是按值传递的。这有助于程序稳定性,因为在函数调用者中无意修改变量不太容易。

      在您的情况下,intArray = malloc(length * sizeof(int)); 不会更改 main() 中指针 array 的值,因此当您取消引用未初始化的指针时,您会得到 未定义的行为(通过几乎功能等效的数组表示法)。

      将指针传递给指针是一种方法:

      void mallocWrapper(int** intArray, int length){...
      
      mallocWrapper(&array, arraySize);
      

      修改函数以返回新指针。

      但是,我不鼓励以这种方式存根标准 C 库函数,因为这会使程序更难阅读和调试:如果我看到对 @987654325 的调用@然后我确切地知道会发生什么。如果我看到mallocWrapper,在我阅读文档或函数源代码之前,我不知道会发生什么。

      【讨论】:

      • 很好的解释。我知道这是一件奇怪的非标准事情。如前所述,这只是一个学生在胡闹。
      • 当然是@Andy T;但我经常遇到充满存根和包装器的专业代码,我依靠你利用你的职位从源头上消除这个问题;-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多