我在尝试分配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[][]
表示法?这可能是不可能的,因为我在编译时不知道任何数组维度。
Why can't we use double pointer to represent two dimensional arrays?
答案 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;
}