-1

我很难将双指针的引用传递给函数。我有这个:

#include <stdio.h>
#include <stdlib.h>   
#include <string.h>

#define MAX_ROWS 2
#define MAX_COLS 2

int main(void){
    int i=0,lenght=0,maxColumns=0,j=0,k=0,maxRows=0,maxColumns2=0;
    int **columnVect;
        /*lengthOfPtr gives me the columns that i need. */
    if((lenght=(lengthOfPtr(ptrMessage)))<=3){
        maxColumns=1;
        maxColumns2=2;
    }else{
        maxColumns=lenght/2;
        maxColumns2=maxColumns;
    }
        /* Allocating Memory for the double pointer. */
    columnVect=malloc(maxColumns2 * sizeof(int*));
    if(columnVect == NULL){
        fprintf(stderr, "Memory error.\n");
        exit(0);
    }

    for(i = 0; i < maxColumns2; i++){
        columnVect[i] = malloc(maxRows * sizeof(int));
        if(columnVect[i] == NULL){
            fprintf(stderr, "Memory error.\n");
            exit(0);
        }
    }

    // Do something that fills columnVect[i][j]

        /* Passing the double pointer to messageVector */
    messageVector(&columnVect,maxColumns);
return 0;
}


int messageVector(int ***columnVect,int maxColumns){
        /* Allocating Memory for the triple pointer. */
    columnVect=(int ***)malloc(sizeof(int **)); 

   //Do something here . . . 

return messageVector;
}

如果我运行程序给我:(lldb)

在:

3 启动 libdyld.dylib`start: 0x7fff88b447e0: nop

任何人都可以告诉我如何以正确的方式做到这一点?谢谢!

4

1 回答 1

1

好的,尽管我不太了解您要使用该messageVector功能完成什么,但我认为您的问题是合理的,因此我将尝试为您提供一些见解。

首先,您在main函数中提供的代码还有另一个问题。如果malloc在分配maxColumns2行时失败,则退出而不使用free任何先前分配的行。

请注意,我故意交换了 and 的措辞maxColumns2maxRows因为在一般情况下它更有意义。从概念上讲,您首先分配int指针行,然后为每一行分配int.

所以,你可以试试这样的东西......

/* Allocating Memory for the double pointer. */

columnVect = malloc( maxRows * sizeof(int *) );
if ( columnVect == NULL ){
    fputs( "Memory error.\n", stderr );
    exit(0);
}

for (int i=0; i < maxRows; i++)
{
    columnVect[i] = malloc( maxColumns2 * sizeof(int) );
    if ( columnVect[i] == NULL )
    {
        fputs( "Memory error.\n", stderr );
        for (int j = i-1; j > -1; j--)
            free( columnVect[j] );
        free( columnVect );
        columnVect = NULL;
        exit(0);
    }
}

内部循环(使用j计数器)从最后一个成功分配的行走向第一行,free并在途中将它们向上移动。之后,columnsVectis 也被free'ed (即为外部循环之前的指针保留的内存int)并设置为NULL.

我可能在这里挑剔,因为大多数现代操作系统会在程序终止后释放程序分配的任何内存,但始终释放已分配的内存是一个好习惯。一方面,它有助于调试代码。如果您需要将当前代码嵌入到更大的项目(例如库)中,它还可以防止您在将来创建内存泄漏。

现在,关于将双指针的引用传递给函数,恕我直言,一个很好的简单示例是释放为该指针保留的内存并将指针设置为NULL. 这些方面的东西:

void free_int2d( int ***int2d, int nrows )
{
    int i;

    if ( nrows < 1 ) {
        printf( "*** warning: %s() failed, no memory freed\n", __func__ );
        return;
    }
    if ( !int2d || !*int2d )
        return;

    for (i=0; i < nrows; i++) {
        if ( (*int2d)[i] )
            free( (*int2d)[i] );
    }

    *int2d = NULL;
}

希望它是不言自明的,但以防万一,让我指出一些事情。

*int2d主要的一个是每当你想在函数内部表达你的原始双指针(即指针的行)时编写int

另一种是当你想表达第i'th行时,你写(*int2d)[i]。您必须将第一个取消引用显式括在括号内...第二个取消引用是通过 [ ] 表示法隐式完成的。

最后,作为通过引用传递一个双指针到这个函数的例子,这里是原始代码的内部循环,使用这个free_int2函数重写......

for (int i=0; i < maxRows; i++)
{
    columnVect[i] = malloc( maxColumns2 * sizeof(int) );
    if ( columnVect[i] == NULL )
    {
        fputs( "Memory error.\n", stderr );
        free_int2d( &columnVect, i );
        exit(0);
    }
}

它大大简化,因此更具可读性。free_2d( &columnVect, maxRows )也应该在程序成功终止时被调用(出于我上面解释的原因)。

编辑

出于性能原因,您可以考虑为列预先分配一个缓冲区malloc,并根据需要重新分配它(可能通过将其大小加倍)。但这会产生更复杂的代码。

于 2013-05-18T22:38:20.237 回答