简体   繁体   English

查找动态分配数组的大小

[英]Find the size of a dynamically allocated array

Let's say we have an array of strings initialized like this:假设我们有一个像这样初始化的字符串数组:

char **a = malloc(3 * sizeof(char*)); //edited

a[0]="asd";
a[1]="fghj";
a[2]="klzxc";

How can we print the first dimension of this 2D array (3)?我们如何打印这个二维数组 (3) 的第一维?

How can we print the first dimension of this 2d array (3)?我们如何打印这个二维数组 (3) 的第一维?

You have to keep track of the number of elements you allocated in a separate variable:您必须跟踪在单独变量中分配的元素数量:

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] );

A pointer, regardless of type, points to (stores the address of) a single object.无论类型如何,指针都指向(存储地址)单个对象。 That single object may be the first in a larger sequence of objects, but there is no way to determine that from pointer value itself.该单个对象可能是较大对象序列中的第一个对象,但无法从指针值本身确定该对象。 If you have the following:如果您有以下情况:

  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 |
                               +---+---+---+---+---+---+

You cannot know from a itself that it points to the first of 3 objects;你不能从a本身知道它指向 3 个对象中的第一个; you cannot know from each a[i] itself that it points to a sequence of char objects.您无法从每个a[i]本身知道它指向一系列char对象。 That information must be tracked separately.该信息必须单独跟踪。 In the case of a we have a separate variable, num_elements , that keeps track of how may elements are in a .在的情况下, a我们有一个独立的变量, num_elements ,持续跟踪可以如何元素是a In the case of each a[i] , we have the string terminator to tell us how long each string is.在每个a[i]的情况下,我们有字符串终止符来告诉我们每个字符串的长度。

How can we print the first dimension of this 2D array (3)?我们如何打印这个二维数组 (3) 的第一维?


A couple of previous points:前面几点:

To be accurate char **a is not a 2D array, it's a pointer to pointer to char .准确地说, char **a不是二维数组,它是一个指向char指针。

A safer way to use this memory allocation would by to use the derefenced pointer instead of the type, this method facilitates the maintenace of the code:使用这种内存分配的一种更安全的方法是使用解除引用的指针而不是类型,这种方法有助于代码的维护:

char **a = malloc(sizeof *a * 3);

Another thing to note is that the string literals assigned to those pointers are read only and cannot be changed.另一件要注意的事情是分配给这些指针的字符串文字是只读的,不能更改。


To answer your question:回答你的问题:

To know the first dimension, ie the number of assigned pointers, you need to keep it in mind, possibly store it, there is no portable way to retrieve the number of pointers you allocated after the fact.要知道第一个维度,分配的指针的数量,您需要记住它,可能会存储它,没有可移植的方法来检索您事后分配的指针数量。

However, there are non-portable methods to do this:但是,有一些不可移植的方法可以做到这一点:

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

As the functions return the number of allocated bytes, dividing their return value by the size of the pointer retrieves the actual number of pointers.当函数返回分配的字节数时,将它们的返回值除以指针的大小可以检索实际的指针数。


If you need actual editable char arrays:如果您需要实际的可编辑字符数组:

If you want to have an array of chars, that you can actually edit and change, you must also allocate memory for each of those three pointers.如果您想要一个字符数组,您可以对其进行实际编辑和更改,您还必须为这三个指针中的每一个分配内存。

eg例如

for(int i = 0; i < 3; i++)
    a[i] = malloc(4) //for char arrays of 3 chars + null byte

After this, to assign a string you'll need to use something like strcpy or preferably memcpy .在此之后,要分配一个字符串,您需要使用类似strcpy或最好是memcpy东西。

eg例如

memcpy(a[0], "asd", 4); //copies "asd" to a[0]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM