查找动态分配数组的大小
Find the size of a dynamically allocated array
假设我们有一个这样初始化的字符串数组:
char **a = malloc(3 * sizeof(char*)); //edited
a[0]="asd";
a[1]="fghj";
a[2]="klzxc";
我们如何打印此二维数组 (3) 的第一个维度?
How can we print the first dimension of this 2D array (3)?
前面几点:
准确地说char **a
不是二维数组,它是指向char
的指针。
使用此内存分配的更安全方法是使用解除引用的指针而不是类型,此方法有助于代码的维护:
char **a = malloc(sizeof *a * 3);
另一件需要注意的事情是,分配给这些指针的字符串文字是只读的,不能更改。
回答你的问题:
要知道第一个维度,即赋值指针的个数,需要记在心里,可能要存起来,没有可移植的方法来检索的个数你在事后分配的指针。
但是,有 non-portable 方法可以做到这一点:
size_t size = _msize(a)/sizeof *a; //Windows
size_t size = malloc_usable_size(a)/sizeof *a; //Linux
size_t size = malloc_size(a)/sizeof *a; //Mac OS
作为函数 return 分配的字节数,将它们的 return 值除以指针的大小得到实际的指针数。
如果您需要实际的可编辑字符数组:
如果您想拥有一个可以实际编辑和更改的字符数组,您还必须为这三个指针中的每一个分配内存。
例如
for(int i = 0; i < 3; i++)
a[i] = malloc(4) //for char arrays of 3 chars + null byte
在此之后,要分配一个字符串,您需要使用 strcpy
之类的东西,或者最好使用 memcpy
.
例如
memcpy(a[0], "asd", 4); //copies "asd" to a[0]
How can we print the first dimension of this 2d array (3)?
您必须跟踪在单独变量中分配的元素数量:
size_t num_elements = 3;
char **a = malloc( sizeof *a * num_elements );
if ( a )
{
a[0] = "asd"; // NOTE: these lines store the addresses of the string
a[1] = "fghj"; // literals in a[0], a[1], and a[2] - you are not copying
a[2] = "klzxc"; // the *contents* of each string, just its address
}
...
for ( size_t i; i < num_elements; i++ )
printf( "a[%zu] = %s\n", i, a[i] );
一个指针,无论类型如何,都指向(存储地址)一个单个对象。该单个对象可能是更大的对象序列中的第一个,但无法从指针值本身确定它。如果您有以下条件:
char ** char * char
+---+ +---+ +---+---+---+---+
a:| | ---> | | a[0] -----> |'a'|'s'|'d'| 0 |
+---+ +---+ +---+---+---+---+
| | a[1] ---+
+---+ | +---+---+---+---+---+
| | a[2] -+ +-> |'f'|'g'|'h'|'j'| 0 |
+---+ | +---+---+---+---+---+
|
| +---+---+---+---+---+---+
+---> |'k'|'l'|'z'|'x'|'c'| 0 |
+---+---+---+---+---+---+
您无法从 a
本身知道它指向 3 个对象中的第一个;您无法从每个 a[i]
本身知道它指向一系列 char
对象。该信息必须单独跟踪。在 a
的情况下,我们有一个单独的变量 num_elements
,它跟踪 a
中元素的数量。在每个 a[i]
的情况下,我们有字符串终止符来告诉我们每个字符串有多长。
假设我们有一个这样初始化的字符串数组:
char **a = malloc(3 * sizeof(char*)); //edited
a[0]="asd";
a[1]="fghj";
a[2]="klzxc";
我们如何打印此二维数组 (3) 的第一个维度?
How can we print the first dimension of this 2D array (3)?
前面几点:
准确地说char **a
不是二维数组,它是指向char
的指针。
使用此内存分配的更安全方法是使用解除引用的指针而不是类型,此方法有助于代码的维护:
char **a = malloc(sizeof *a * 3);
另一件需要注意的事情是,分配给这些指针的字符串文字是只读的,不能更改。
回答你的问题:
要知道第一个维度,即赋值指针的个数,需要记在心里,可能要存起来,没有可移植的方法来检索的个数你在事后分配的指针。
但是,有 non-portable 方法可以做到这一点:
size_t size = _msize(a)/sizeof *a; //Windows
size_t size = malloc_usable_size(a)/sizeof *a; //Linux
size_t size = malloc_size(a)/sizeof *a; //Mac OS
作为函数 return 分配的字节数,将它们的 return 值除以指针的大小得到实际的指针数。
如果您需要实际的可编辑字符数组:
如果您想拥有一个可以实际编辑和更改的字符数组,您还必须为这三个指针中的每一个分配内存。
例如
for(int i = 0; i < 3; i++)
a[i] = malloc(4) //for char arrays of 3 chars + null byte
在此之后,要分配一个字符串,您需要使用 strcpy
之类的东西,或者最好使用 memcpy
.
例如
memcpy(a[0], "asd", 4); //copies "asd" to a[0]
How can we print the first dimension of this 2d array (3)?
您必须跟踪在单独变量中分配的元素数量:
size_t num_elements = 3;
char **a = malloc( sizeof *a * num_elements );
if ( a )
{
a[0] = "asd"; // NOTE: these lines store the addresses of the string
a[1] = "fghj"; // literals in a[0], a[1], and a[2] - you are not copying
a[2] = "klzxc"; // the *contents* of each string, just its address
}
...
for ( size_t i; i < num_elements; i++ )
printf( "a[%zu] = %s\n", i, a[i] );
一个指针,无论类型如何,都指向(存储地址)一个单个对象。该单个对象可能是更大的对象序列中的第一个,但无法从指针值本身确定它。如果您有以下条件:
char ** char * char
+---+ +---+ +---+---+---+---+
a:| | ---> | | a[0] -----> |'a'|'s'|'d'| 0 |
+---+ +---+ +---+---+---+---+
| | a[1] ---+
+---+ | +---+---+---+---+---+
| | a[2] -+ +-> |'f'|'g'|'h'|'j'| 0 |
+---+ | +---+---+---+---+---+
|
| +---+---+---+---+---+---+
+---> |'k'|'l'|'z'|'x'|'c'| 0 |
+---+---+---+---+---+---+
您无法从 a
本身知道它指向 3 个对象中的第一个;您无法从每个 a[i]
本身知道它指向一系列 char
对象。该信息必须单独跟踪。在 a
的情况下,我们有一个单独的变量 num_elements
,它跟踪 a
中元素的数量。在每个 a[i]
的情况下,我们有字符串终止符来告诉我们每个字符串有多长。