Se utiliza punteros.
Específicamente, usa un puntero a una dirección, y usando una función de biblioteca c estándar llama, le pide al sistema operativo que expanda el montón para permitirle almacenar lo que necesita.
Ahora, podría rechazar, que deberá manejar.
La siguiente pregunta es: ¿cómo se solicita una matriz 2D? Bueno, solicite una serie de punteros y luego expanda cada puntero.
Como ejemplo, considere esto:
int i = 0;
char** words;
words = malloc((num_words)*sizeof(char*));
if (words == NULL)
{
/* we have a problem */
printf("Error: out of memory.\n");
return;
}
for (i=0; i<num_words; i++)
{
words[i] = malloc((word_size+1)*sizeof(char));
if (words[i] == NULL)
{
/* problem */
break;
}
}
if (i != num_words)
{
/* it didn't allocate */
}
Esto se obtiene una matriz de dos dimensiones, donde cada elemento words[i]
puede tener un tamaño diferente, puede determinar en tiempo de ejecución, así como el número de palabras es.
Tendrá que free()
toda la memoria resultante mediante un bucle sobre la matriz cuando haya terminado con él:
for (i = 0; i < num_words; i++)
{
free(words[i]);
}
free(words);
Si no, vamos a crear una pérdida de memoria.
También podría usar calloc
. La diferencia está en convención y efecto de llamada: calloc
inicializa toda la memoria en 0
, mientras que malloc
no.
Si necesita cambiar el tamaño en tiempo de ejecución, use realloc
.
también, importante, Cuidado con el word_size + 1 que he utilizado. Las cadenas en C tienen terminación cero y esto requiere un carácter adicional que debe tener en cuenta. Para asegurarme de que recuerdo esto, generalmente establezco el tamaño de la variable word_size
en cualquier tamaño de la palabra (la longitud de la cadena como espero) y dejo explícitamente el +1 en el malloc para el cero. Entonces sé que el búfer asignado puede tomar una cadena de word_size
caracteres. No hacer esto también está bien, solo lo hago porque me gusta explicar explícitamente el cero de una manera obvia.
También hay una desventaja en este enfoque: he visto explícitamente esto como un error enviado recientemente. Aviso que escribí (word_size+1)*sizeof(type)
- imagine sin embargo que había escrito word_size*sizeof(type)+1
. Para sizeof(type)=1
, estas son la misma cosa, pero Windows usa wchar_t
con mucha frecuencia, y en este caso reservará un byte para su último cero en lugar de dos, y son elementos terminados en cero del tipo type
, no solo cero bytes. Esto significa que se sobrepasará en lectura y escritura.
Adición: hazlo como quieras, solo ten cuidado con esos terminadores cero si vas a pasar el búfer a algo que depende de ellos.
Tu terminología parece un poco confusa aquí. Esperaría que num_words == 2 implica que debería haber dos palabras y palabras [0] y las palabras [1] las contienen. Debería entonces malloc (num_words * sizeof (char *)). –
@Sam tienes razón. Creo que lo dije con respecto al +1 para dar cuenta del cero terminador. Reparar :) –
¿De dónde viene la variable 'num_words'? –