"Desreferenciar" significa un puntero acceder al valor de los puntos de puntero a. Asumir las siguientes declaraciones:
int a = 10;
int *p = &a;
Así es un mapa de memoria hipotética de las dos variables:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
a 0x80001000 0x00 0x00 0x00 0x0A
p 0x80001004 0x80 0x00 0x10 0x00
a
contiene el valor entero 10. p
contiene la dirección del a
(0x80001000). Si queremos acceder al contenido de a
a través de p
, desreferenciap
con el operador de direccionamiento indirecto *
. Por lo tanto, la expresión *p
es equivalente a la expresión a
. Si escribimos
*p = 16;
que es lo mismo que escribir
a = 16;
Aquí está un breve fragmento de código que muestra cómo utilizar un objeto de tipo char **
para crear una matriz de cadenas:
#include <stdlib.h>
#define N 20 // For this example, we will allocate 20 strings
#define LENGTH 10 // of 10 characters each (not counting 0 terminator)
...
char **arr = malloc(sizeof *arr * N);
if (arr)
{
size_t i;
for (i = 0; i < N; i++)
{
arr[i] = malloc(sizeof *arr[i] * (LENGTH + 1));
strcpy(arr[i], " ");
}
}
Al pasar por línea por línea,
char **arr = malloc(sizeof *arr * N);
asigna un bloque de N elementos, cada uno lo suficientemente grande para almacenar un puntero a char (sizeof *arr
== sizeof (char *)
ya que el tipo de *arr
== char *
), y asigna el valor del puntero resultante a arr
. IOW, arr
apunta al primer puntero a char
, de ahí el tipo char **
. Tenga en cuenta que si usted se separó la declaración y la llamada de función, que se vería así
char **arr;
...
arr = malloc(sizeof *arr * N);
Queremos asignar el resultado de malloc
a arr
, no a lo que arr
puntos a.
if (arr)
Es posible que malloc
a fallar, por lo que queremos comprobar el resultado antes de usarlo. En caso de que falle malloc
, devolverá un valor de puntero NULL.
{
size_t i;
for (i = 0; i < N; i++)
{
arr[i] = malloc(sizeof *arr[i] * (LENGTH + 1));
Para cada puntero de carácter arr[i]
, asignamos un bloque de memoria lo suficientemente grande para la longitud 1 elementos +, cada una lo suficientemente grande como para contener un valor char
(sizeof *arr[i] == sizeof (char)
, ya que el tipo de *arr[i] == char
; tenga en cuenta que sizeof (char)
es siempre 1) y asigne el resultado al arr[i]
.
Dado que asignamos cada cadena con una llamada malloc
por separado, es poco probable que sean contiguas en la memoria. Aquí hay otro mapa de memoria que muestra una posible resultado del código anterior:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
arr 0x80001000 0xA0 0xCC 0x00 0x00
...
arr[0] 0xA0CC0000 0xA0 0xCC 0x20 0x00
arr[1] 0xA0CC0004 0xA0 0xCC 0x20 0x40
arr[2] 0xA0CC0008 0xA0 0xCC 0x21 0x28
...
arr[19] 0xA0CC0014 0xA0 0xCC 0x23 0x10
...
arr[0][0] 0xA0CC2000 ' ' ' ' ' ' ' '
arr[0][4] 0xA0CC2004 ' ' ' ' ' ' ' '
arr[0][8] 0xA0CC2008 ' ' ' ' 0x00 0x??
...
arr[1][0] 0xA0CC2040 ' ' ' ' ' ' ' '
arr[1][4] 0xA0CC2044 ' ' ' ' ' ' ' '
arr[1][8] 0xA0CC2048 ' ' ' ' 0x00 0x??
...
Disculpa, soy un novato, así que tal vez esté mal, pero para limpiar totalmente después de la asignación, deberías recorrer el número total de cadenas y el acceso gratuito [i ] así como liberar toda la matriz libre (arr), ¿es así? ¿O sería suficiente simplemente 'free (arr);'? –