【发布时间】:2021-01-15 06:44:40
【问题描述】:
假设我们有一个这样初始化的字符串数组:
char **a = malloc(3 * sizeof(char*)); //edited
a[0]="asd";
a[1]="fghj";
a[2]="klzxc";
我们如何打印这个二维数组的第一个维度 (3)?
【问题讨论】:
标签: arrays c memory-management dynamic-memory-allocation sizeof
假设我们有一个这样初始化的字符串数组:
char **a = malloc(3 * sizeof(char*)); //edited
a[0]="asd";
a[1]="fghj";
a[2]="klzxc";
我们如何打印这个二维数组的第一个维度 (3)?
【问题讨论】:
标签: arrays c memory-management dynamic-memory-allocation sizeof
我们如何打印这个二维数组的第一个维度 (3)?
之前的几点:
准确地说char **a 不是二维数组,它是指向char 的指针。
使用这种内存分配的更安全的方法是使用取消引用的指针而不是类型,这种方法有利于代码的维护:
char **a = malloc(sizeof *a * 3);
另外需要注意的是,分配给这些指针的字符串文字是只读的,不能更改。
回答您的问题:
要知道第一个维度,ie分配的指针数量,你需要记住它,可能存储它,没有可移植的方法来检索你分配的指针数量之后事实。
但是,有一些不可移植的方法可以做到这一点:
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
当函数返回分配的字节数时,将它们的返回值除以指针的大小得到实际的指针数。
如果您需要实际的可编辑字符数组:
如果您想拥有一个可以实际编辑和更改的字符数组,您还必须为这三个指针中的每一个分配内存。
例如
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]
【讨论】:
我们如何打印这个二维数组的第一个维度 (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],我们都有字符串终止符来告诉我们每个字符串有多长。
【讨论】: