指针参数损坏:返回指针或传递指针的地址工作

时间:2011-12-24 18:56:26

标签: c pointers parameters

我将指向用户定义类型的指针传递给malloc内存的函数,并将此指针设置为指向它。 malloc()返回一个指针,但是当我从函数返回时,我的指针被破坏了。我想出了几个修复:

  • 返回指针而不是传递它
  • 传递指针的地址而不是指针本身

我怀疑这类似于FILE指针的情况;如果你将指针传递给一个函数,你就不能指望指针没有被改变,因为系统可能会把它弄乱。所以你改为传递FILE *的地址。

有人对此有解释吗?这是代码(抱歉,它有点长):

typedef struct  {
    BOOK *bookAry;
    int numBooks;
}INVENTORY;

我在main()中有这个,其中INVENTORY是上面用户定义的类型:

//variable declarations
INVENTORY *inv = NULL;

//process
initInventory( inv, bookArySize );
processFile( inv );

initInventory()功能如下:

void initInventory( INVENTORY *inv, int size ) {

    //process
    inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
       //more code here....
    return;

}//initInventory

所以我们返回main()(我们认为),inv指向新分配的内存(并且inv指向具有其他指针的结构)。只有当我将指针inv传递给processFile()时,它才会被破坏,当我尝试引用inventory结构中的数据时,我会遇到访问冲突。事实证明返回main()时指针无效!

修正了它:main()有:

//variable declarations
INVENTORY *inv = NULL;

//process
inv = initInventory( inv, bookArySize );
processFile( inv );

initInventory()更改为:

INVENTORY * initInventory( INVENTORY *inv, int size ) {

    //process
    inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );


    //return a pointer to the INVENTORY header struct
    return inv;

}//initInventory

然后我尝试了这个,我认为这是一个更好的解决方案。 main()现在有:

//variable declarations
INVENTORY *inv = NULL;
    //more code here...

//process
initInventory( &inv, bookArySize );
processFile( inv );

initInventory()如下:

void initInventory( INVENTORY **inv, int size ) {

    //process
    *inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
        //more code here....
    return;

}//initInventory

2 个答案:

答案 0 :(得分:0)

你在这里做什么:

void initInventory( INVENTORY *inv, int size ) {

    //process
    inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
    //more code here....
    return;

}//initInventory

基本上是这样的:您将地址的副本作为参数传递,然后更改副本。它与在该函数内为size分配内容具有相同的效果:它只是更改本地副本。

你的“修复”是两个正确的解决方案:传入一个指向你想要改变的变量的指针(在这种情况下它是一个指向指针的指针)或者返回malloc的指针。

btw:你不应该转换malloc的返回值。你什么也得不到,隐藏了潜在的问题另请参阅this question

答案 1 :(得分:0)

基本上,如果按值传入指针,则会将其复制到参数中并且调用函数指针不能被调用函数更改 - malloc()分配给传递的参数OK,但是对副本的更改是从函数返回时丢失 - * INV保持为NULL。显式返回指针或通过引用传入指针(**)都很好 - malloc()返回的指针被加载到调用者变量中,因此调用者在返回后可以成功解引用。

与FILE指针的问题相同。如果您打算在被调用函数内打开文件并在返回后在调用者中访问它,则无法通过值传入FILE *。