变量2d char *数组作为C中的返回值

时间:2015-11-06 18:02:49

标签: c arrays pointers

我在尝试分配char的2d数组并从函数返回时遇到了麻烦。

//my return type needs to change to something like (char*)[]?
char **readData( size_t numRows, size_t numCols )
{
    //I think this needs to chage to something like this:
    //char* (*data)[numRows] = malloc(sizeof(char*) * numCols );
    char **data = malloc( sizeof(char*) * numRows * numCols );

    for( size_t r=0; r < numRows; ++r ) {
        for(size_t c=0; c < numCols; ++c) {     
            data[r*numRows+c] = strdup( getString() );

            //I'd like this to be:
            //data[r][c] = strndup( getString() );
        }
    }

    return data;
}

int main()
{
    size_t rows = 5;
    size_t cols = 7;
    char **data = readData( rows, cols );

    if( data != NULL ) {

        for( int r=0; r < rows; ++r ) {
            for( int c=0; c < cols; ++c ) {
                printf( "[%i][%i] = %s\n", r, c, data[r*rows+c] );
                free(data[r*rows+c]);
                data[r*rows+c] = NULL;

                //I'd really like this to be:
                //printf( "[%i][%i] = %s\n", r, c, data[r][c] );
                //free(data[r][c]);
                //data[r][c] = NULL;
            }
        }

        free(data);
        data = NULL;
    }

    return 0;
}

我有两个问题:

1)上面的代码以某种方式被破坏了。当我不期望它时,printf打印出NULL。我必须在某个地方搞砸索引。

2)我相信在C99中我可以使用更熟悉的data[][]表示法来索引2d指针数组。我在上面的代码中有注释的更改,但我不知道将函数的返回类型设置为什么。如何更改程序以使用data[][]表示法?这可能是不可能的,因为我在编译时不知道任何数组维度。

我已经看过以下堆栈溢出问题,但似乎仍无法理解它: enter image description here

Why can't we use double pointer to represent two dimensional arrays?

How to return a two-dimensional pointer in C?

2 个答案:

答案 0 :(得分:2)

您有一个二维网格字符串,因此您的数据结构为char ***。所有级别的数据都是动态分配的。

data是动态numRows行数组的句柄。每行data[r]numCols字符串动态数组的句柄;这些数组也必须明确分配。每个字符串data[r][c]都是动态数组字符的句柄,您可以通过strdup创建这些字符。

所以你的代码可能如下:

char ***readData(size_t numRows, size_t numCols)
{
    char ***data = malloc(numRows * sizeof(*data));

    for (size_t r=0; r < numRows; ++r) {
        data[r] = malloc(numCols * sizeof(*data[r]));

        for(size_t c=0; c < numCols; ++c) {     
            data[r][c] = strdup(getString());
        }
    }

    return data;
}

int main()
{
    size_t rows = 5;
    size_t cols = 7;
    char ***data = readData(rows, cols);

    if (data != NULL) {
        for (int r = 0; r < rows; ++r) {
            for (int c = 0; c < cols; ++c) {
                printf("[%i][%i] = \"%s\"\n", r, c, data[r][c]);
                free(data[r][c]);
            }
            free(data[r]);
        }
        free(data);
    }

    return 0;
}

答案 1 :(得分:-1)

以下代码实现了numRows x numCols

的2D数组

每次调用malloc()后,您都需要添加错误检查(返回值!= NULL),以确保操作成功。

它最初会清除所有指针,因此很容易将每个指针传递给free()而不必担心指针是否实际包含有效指针(free()正确处理NULL指针)

#define _GNU_SOURCE

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

char * getString( void );

//my return type needs to change to something like (char*)[]?
char **readData( size_t numRows, size_t numCols )
{
    // following results in an array of pointers to char, 1 ptr per row
    char **data = malloc( sizeof(char*) * numRows );

    // set all row pointers to NULL, to make it easier to free all the allocations
    memset( data, 0x00, sizeof( char*) *numRows );

    for( size_t r=0; r<numRows; r++)
    { // for each row
        data[r] = malloc( sizeof( char *) * numCols) ;
        // set all column ptrs to NULL, to kame it easier to free all the allocations
        memset( data[r], 0x00, sizeof( char * ) * numCols) ;
    }


    // set all the column pointers in each row
    for( size_t r=0; r < numRows; ++r )
    {
        for(size_t c=0; c < numCols; ++c)
        {
            char ** pRow = data+r; // get ptr to row entry
            char ** pCol = pRow+c;    // get ptr to column entry
            *pCol = strdup( getString() );
        }
    }

    return data;
}