关于malloc的功能访谈

时间:2017-03-22 16:11:24

标签: c function pointers memory-leaks malloc

我在接受公司采访时遇到了一个问题,我无法弄清楚答案的原因。

void newArray(int* local, int size) 
{
     local = (int*) malloc( size * sizeof(int) );
}
int main() {
     int* ptr;
     newArray(ptr, 10);
}

Ans:这会导致内存泄漏,程序不正确。

有谁知道为什么这段代码无效?

5 个答案:

答案 0 :(得分:8)

在C中,所有函数参数都是按值传递的。因此,当在local内部修改局部变量newArray时,更改在函数外部不可见。所以内存指针丢失了,你有内存泄漏。

要修复泄漏,函数应该接受指针的地址(即指向指针的指针),然后取消引用该指针,使ptrmain中}已更新。然后,您需要调用free来释放内存。

void newArray(int **local, int size) 
{
     *local = malloc( size * sizeof(int) );
}
int main() {
     int* ptr;
     newArray(&ptr, 10);
     free(ptr);
}

另外,don't cast the return value of malloc

答案 1 :(得分:3)

它不能工作,因为它改变了函数内部参数的值,但由于C是按值调用的,该函数与用作该参数之外的变量的值具有 no 关系功能

换句话说,&local中的newArray()&ptr中的main()不同;他们不同的变量所以改变一个变量对另一个没有影响。

答案 2 :(得分:3)

您将丢失对malloced内存的引用。这应该是好的。

void newArray(int** local, int size) 
{
     *local = (int*) malloc( size * sizeof(int) );
}
int main(c,v) char **v; {
    int* ptr;
    newArray(&ptr, 10);
    /* Do something with ptr? */
    free(ptr);
}

答案 3 :(得分:3)

对于初学者这个程序

void newArray(int* local, int size) 
{
     local = (int*) malloc( size * sizeof(int) );
}
int main() {
     int* ptr;
     newArray(ptr, 10);
}

表明在面试中提出这个问题的人并不是一个C程序员。

首先,根据C标准,不带参数的函数main应声明为

int main( void )

其次,没有任何理由将函数newArray的第二个参数声明为类型int而不是类型size_t,因为使用了标准函数malloc在函数中有一个size_t类型的参数。

否则函数应检查传递给函数的参数是否为负值。

至于问题,那么函数参数就是它的局部变量。它们由提供的参数初始化。您可以通过以下方式设想函数定义及其调用

newArray(ptr, 10);

// ...

void newArray( /* int* local, int size */ ) 
{
    int *local = ptr;
    int size = 10;

    local = (int*) malloc( size * sizeof(int) );
}

正如您所看到的,它是在函数内部更改的参数(即局部变量)local。论证本身保持不变。仅使用参数的值初始化参数。退出函数后,其局部变量(包括其参数)不会存活并被破坏。

因此该函数确实存在内存泄漏。

如果您希望在函数中更改其值,则应通过引用传递参数。例如

void newArray( int **local, size_t size  ) 
               ^^^^^^^^^^^^^^^^^^^^^^^^
{
    *local = (int*) malloc( size * sizeof(int) );
}

该函数应该像

一样调用
newArray( &ptr, 10 );

然而,在重新分配之前,问题出现了如何处理指针*local的值。是否应该在调用malloc之前调用函数free

因此更清晰的函数定义可能看起来像

int * newArray( size_t size ) 
{
    return malloc( size * sizeof( int ) );
}

在这种情况下,该函数的客户端决定用他自己的指针做什么,他将重新分配。

答案 4 :(得分:1)

指针ptr按值传递(与C中的其他所有内容一样)。因此,将malloc的返回值指定为local只会更改本地变量,而不会更改ptr中的main()

因此,一旦函数malloc()返回,就无法访​​问newArray返回的指针。因此,它会导致内存泄漏

它类似于:

void func(int x)
{
    x = 42;
}

int main(void)
{
   int y = 0;
   func(y);
   /* 'y' remains 0 */
}