Discussion:
Memoria dinámica para una matriz
(demasiado antiguo para responder)
Fernando
2005-03-22 18:30:11 UTC
Permalink
Si quiero reservar de forma dinámica memoria para un vector de n
enteros, lo que hago es:

int *vector;

vector = (int *) malloc (n * sizeof(int));



¿Que debo hacer si quiero reservar memoria de forma dinámica para una
matriz de n * n elementos??
Lepton
2005-03-22 22:01:05 UTC
Permalink
On Tue, 22 Mar 2005, Fernando wrote:

# Si quiero reservar de forma dinámica memoria para un vector de n enteros, lo
# que hago es:
#
# int *vector;
#
# vector = (int *) malloc (n * sizeof(int));
#
# ¿Que debo hacer si quiero reservar memoria de forma dinámica para una matriz
# de n * n elementos??

Eso depende de como vas luego a acceder a esa matriz, pero una forma
muy simple es:

matriz = (int *) malloc (n * n * sizeof(int));

y luego para acceder a matriz[i,j] seria matriz[i*n + j] si almacenas
la matriz por filas, o matriz[i + n*j] si la almacenas por columnas.

Lepton.
fermath
2005-03-23 23:41:33 UTC
Permalink
Post by Lepton
# Si quiero reservar de forma dinámica memoria para un vector de n enteros, lo
#
# int *vector;
#
# vector = (int *) malloc (n * sizeof(int));
#
# ¿Que debo hacer si quiero reservar memoria de forma dinámica para una matriz
# de n * n elementos??
Eso depende de como vas luego a acceder a esa matriz, pero una forma
matriz = (int *) malloc (n * n * sizeof(int));
y luego para acceder a matriz[i,j] seria matriz[i*n + j] si almacenas
la matriz por filas, o matriz[i + n*j] si la almacenas por columnas.
Lepton.
La otra forma es:

int **matriz,i;

matriz=(int **)malloc(n* sizeof(int *)); /* n punteros uno por fila */
for(i=0;i<n;i++)
matriz[i]=(int*)malloc(n*sizeof(int)); /* reserva espacio para la fila i */

y se accede matriz[i][j];

para liberarla lo mismo:

for(i=0;i<n;i++)
free(matriz[i]);
free(matriz);

Desde el puunto de vista de gestión de memoria es más eficiente la
primera opción (la de Lepton)

Salud

fermath
David Serrano (Hue-Bond)
2005-03-27 20:05:54 UTC
Permalink
Post by fermath
matriz=(int **)malloc(n* sizeof(int *)); /* n punteros uno por fila */
¿Por qué "(int **)malloc"?

$ cat malloc1.c
int main () {
int *a = malloc (sizeof (int));
return 0;
}
$ cat malloc2.c
#include <stdlib.h>
int main () {
int *a = malloc (sizeof (int));
return 0;
}

$ make malloc1
cc -march=athlon-xp -mfpmath=sse -msse -mmmx -m3dnow -pipe malloc1.c -o malloc1
malloc1.c: En la función `main':
malloc1.c:2: aviso: inicialización se crea un puntero desde un entero sin una conversión
$ make malloc2
cc -march=athlon-xp -mfpmath=sse -msse -mmmx -m3dnow -pipe malloc2.c -o malloc2
$ _
--
David Serrano
Antoine Leca
2005-03-30 14:00:46 UTC
Permalink
Post by David Serrano (Hue-Bond)
Post by fermath
matriz=(int **)malloc(n* sizeof(int *)); /* n punteros uno por fila */
¿Por qué "(int **)malloc"?
Por que dos líneas más arriba está la declaración de matriz.
Post by David Serrano (Hue-Bond)
malloc1.c:2: aviso: inicialización se crea un puntero desde un entero sin una conversión
Vale. Y cuando se modifica la declaración de matriz para long** (sin
corregir la llamada a malloc()), ¿qué te dice tu compilador?

(Sabiendo que para tú, no habrá problemas, por que segun todas
probabilidades LONG_MAX==INT_MAX).

Hay argumentos para los dos campos.


Antoine
David Serrano (Hue-Bond)
2005-03-31 22:49:48 UTC
Permalink
Post by Antoine Leca
Post by David Serrano (Hue-Bond)
¿Por qué "(int **)malloc"?
Por que dos líneas más arriba está la declaración de matriz.
Precisamente esa es la razón por la que gcc sabe a qué debe convertir el
puntero. Nosotros no necesitamos decírselo.
Post by Antoine Leca
Post by David Serrano (Hue-Bond)
malloc1.c:2: aviso: inicialización se crea un puntero desde un
entero sin una conversión
Vale. Y cuando se modifica la declaración de matriz para long** (sin
corregir la llamada a malloc()), ¿qué te dice tu compilador?
Probablemente un error, pero me lo tendría ganado por no #incluir
<stdlib.h>. El malloc2 no da error ni lo dará si cambio el tipo de dato.
Precisamente por eso he mostrado los dos programas :^). El 2 es el bueno.
--
David Serrano
Antoine Leca
2005-04-01 11:07:51 UTC
Permalink
Post by David Serrano (Hue-Bond)
Post by Antoine Leca
Post by David Serrano (Hue-Bond)
malloc1.c:2: aviso: inicialización se crea un puntero desde un
entero sin una conversión
Vale. Y cuando se modifica la declaración de matriz para long**
(sin corregir la llamada a malloc()), ¿qué te dice tu compilador?
Probablemente un error,
No. El compilador no te dice nada. Y es el problema.

# type malloc3.c
#include <stdlib.h>

int main () {
double *a = malloc (sizeof (float));
return a ? free(a), EXIT_SUCCESS : EXIT_FAILURE;
}

# gcc -W -Wall -ansi -pedantic malloc3.c

# gcc -v
Reading specs from bin/../lib/gcc/mingw32/3.4.2/specs
Configured with:
../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=
mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --en
able
-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared
--e
nable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enabl
e-ja
va-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchr
oniz
ation --enable-libstdcxx-debug
Thread model: win32
gcc version 3.4.2 (mingw-special)


:-(
(He utilizado double y float para que vees que incluso cuando son de tamaño
diferente en la plataforma, no se entere.)
Post by David Serrano (Hue-Bond)
pero me lo tendría ganado por no #incluir <stdlib.h>.
No digo eso. Es *preciso* incluirlo, en cualquier caso. Por ejamplo, en 64
bits (Linux or Windows sería ígual), si no lo incluyes, el compilador se
equivocaría a copiar solo 32 bits en a.
Post by David Serrano (Hue-Bond)
El malloc2 no da error ni lo dará si cambio el tipo de
dato.
malloc3 (malloc2 con el tipo cambiado una vez pero no en la llamada a
malloc) no da error, pero es un monstruo. Es demasiado senzillo y
functionará. Pero cambies para una alocación de tabla, y cambies int por
long, y te resulta un programa que functiona bién en un PC normal y
corriente, y explota fuera.


Mientras tanto

# type malloc4.c
#include <stdlib.h>

#define NUM_ELEM 100

int main () {
long **a;

/* muchas instruciones */

a = (int**)malloc (NUM_ELEM * sizeof (int));


return a ? free(a), EXIT_SUCCESS : EXIT_FAILURE;
}

# gcc -W -Wall -ansi -pedantic malloc4.c
malloc4.c: In function `main':
malloc4.c:10: warning: assignment from incompatible pointer type


Antoine
Luis Angel Fdez. Fdez.
2005-04-01 12:52:53 UTC
Permalink
A las 11:07 del viernes 01 de abril,
Antoine Leca <***@localhost.invalid>
hablando de Re: Memoria dinámica para una matriz
en es.comp.lenguajes.c dijo...

Hola

[...]

Bueno, con el fin de aportar algo, aunque no creo que pueda
aportar mucho, sólo decir que por lo que tengo leido por las
news, lo que se recomienda es no utilizar el cast para evitar
camuflar un posible error o warning en caso de olvidar incluir
la cabecera stdlib.h. Y en el sizeof no utilizar el tipo del
dato si no el dato.

Algo como: int *a = malloc(sizeof *a);

Así ante un cambio del tipo de la variable a, el malloc siempre
reservaría memoria para el tipo correcto.

Al menos eso es lo que suelo leer por ahí :)

Ta llueu.
--
Slackware 10.1.0 Kernel 2.6.10 i686 (GCC) 3.3.5
AMD Athlon(tm) 64 Processor 3200+ ( 2200.707MHz )
Linux User #99754 Jabber: ***@jabber.org
Hattrick: C.D. Arrancatapinos (488047) VII.489
fermath
2005-04-02 22:00:49 UTC
Permalink
Post by Luis Angel Fdez. Fdez.
A las 11:07 del viernes 01 de abril,
hablando de Re: Memoria dinámica para una matriz
en es.comp.lenguajes.c dijo...
Hola
[...]
Bueno, con el fin de aportar algo, aunque no creo que pueda
aportar mucho, sólo decir que por lo que tengo leido por las
news, lo que se recomienda es no utilizar el cast para evitar
camuflar un posible error o warning en caso de olvidar incluir
la cabecera stdlib.h. Y en el sizeof no utilizar el tipo del
dato si no el dato.
Algo como: int *a = malloc(sizeof *a);
Así ante un cambio del tipo de la variable a, el malloc siempre
reservaría memoria para el tipo correcto.
Al menos eso es lo que suelo leer por ahí :)
Ta llueu.
Bueno, sólo decir que puse el ínclito (int **)malloc porque en el
mensaje original de Fernando se hacía cast, para que quedara más claro
qué es lo que se reserva en cada sitio.

Salut

fermath
David Serrano (Hue-Bond)
2005-04-02 23:57:08 UTC
Permalink
Post by fermath
Bueno, sólo decir que puse el ínclito (int **)malloc porque en el
mensaje original de Fernando se hacía cast, para que quedara más claro
qué es lo que se reserva en cada sitio.
malloc() sabe lo que se reserva. Si luego resulta que el programador cambia
el tipo de la variable, no tiene que hacer una sustitución masiva a lo largo
y ancho de todo el programa para "actualizar" los malloc()s.

Si el compilador se queja, la solución es #incluir stdlib.h, no hacer un
cast para que se calle. Esto dará problemas más adelante.
--
David Serrano
Antoine Leca
2005-04-04 16:54:51 UTC
Permalink
Post by David Serrano (Hue-Bond)
Si el compilador se queja, la solución es #incluir stdlib.h, no
hacer un cast para que se calle.
No creo que nadie hubo tal idea.
Post by David Serrano (Hue-Bond)
Esto dará problemas más adelante.
Cierto.


Antoine
David Serrano (Hue-Bond)
2005-04-04 18:13:49 UTC
Permalink
Post by Antoine Leca
Post by David Serrano (Hue-Bond)
Esto dará problemas más adelante.
Cierto.
"Esto", ¿el qué?

Si revisas mi mensaje, verás que "esto" == "usar casts", con lo que ahora
mismo me estarías dando la razón.
--
David Serrano
Antoine Leca
2005-04-05 16:40:27 UTC
Permalink
Post by David Serrano (Hue-Bond)
Post by Antoine Leca
Post by David Serrano (Hue-Bond)
Esto dará problemas más adelante.
Cierto.
"Esto", ¿el qué?
Lo habia entendido por el conjunto «corregir advertancias (debidas a un
header olvidado) con casts, para que se calle». Lo siento.
Post by David Serrano (Hue-Bond)
Si revisas mi mensaje, verás que "esto" == "usar casts", con lo que
ahora mismo me estarías dando la razón.
Lo siento mucho. No soy castellanohablante, y me cuesta mucho a veces
entender las sutilidades del idioma. En este caso he aplicado ciegamente las
reglas del francés, que hacen que el pronombre se aplica a toda la
proposición. Si la grámatica castellana hace que el pronombre «esto» solo
recoge el substantivo «un cast», pués efectivamente mi frase no tiene el
sentido que intentaba. Pero no sé como se debería escribir correctamente. Lo
siento mucho.

Creo que ahora puedes entender un poco más la idea que tenía.


Antoine
David Serrano (Hue-Bond)
2005-04-05 20:27:08 UTC
Permalink
No soy castellanohablante, y me cuesta mucho a veces entender las
sutilidades del idioma. En este caso he aplicado ciegamente las reglas del
francés, que hacen que el pronombre se aplica a toda la proposición.
Ah, interesante. Se nota que no lo eres ;^) pero si supiera que el francés
tiene esa regla seguramente me habría explicado de otra forma.
--
David Serrano
David Serrano (Hue-Bond)
2005-04-02 23:54:21 UTC
Permalink
Post by Antoine Leca
No. El compilador no te dice nada. Y es el problema.
Post by David Serrano (Hue-Bond)
pero me lo tendría ganado por no #incluir <stdlib.h>.
No digo eso. Es *preciso* incluirlo, en cualquier caso.
a = (int**)malloc (NUM_ELEM * sizeof (int));
malloc4.c:10: warning: assignment from incompatible pointer type
Es que precisamente, de lo que yo estoy hablando es de la presencia o
ausencia del cast, no de que malloc() nos deje reservar sizeof(long long)
para luego asignar a un int.
--
David Serrano
Antoine Leca
2005-04-04 16:53:02 UTC
Permalink
Post by David Serrano (Hue-Bond)
Post by Antoine Leca
No. El compilador no te dice nada. Y es el problema.
a = (int**)malloc (NUM_ELEM * sizeof (int));
malloc4.c:10: warning: assignment from incompatible pointer type
Es que precisamente, de lo que yo estoy hablando es de la presencia
o ausencia del cast, no de que malloc() nos deje reservar
sizeof(long long) para luego asignar a un int.
Lo que estoy diciendo yo, es que con el cast ganarás una advertancía el día
que te cambian el tipo del elemento. Si no lo pones, tal como lo has
propuesto, no habrá advertancía, peró si problemas. Incluso con #include y
todo.


Antoine
David Serrano (Hue-Bond)
2005-04-04 18:12:18 UTC
Permalink
Post by Antoine Leca
Lo que estoy diciendo yo, es que con el cast ganarás una advertancía el día
que te cambian el tipo del elemento.
Por tanto tocará cambiar los casts de toooodo el código.
Post by Antoine Leca
Si no lo pones, tal como lo has propuesto, no habrá advertancía, peró si
problemas.
No veo cuáles.
--
David Serrano
Horst Kraemer
2005-04-03 10:56:51 UTC
Permalink
Post by Antoine Leca
Post by David Serrano (Hue-Bond)
Post by fermath
matriz=(int **)malloc(n* sizeof(int *)); /* n punteros uno por fila */
¿Por qué "(int **)malloc"?
Por que dos líneas más arriba está la declaración de matriz.
Post by David Serrano (Hue-Bond)
malloc1.c:2: aviso: inicialización se crea un puntero desde un
entero sin una conversión
Vale. Y cuando se modifica la declaración de matriz para long** (sin
corregir la llamada a malloc()), ¿qué te dice tu compilador?
(Sabiendo que para tú, no habrá problemas, por que segun todas
probabilidades LONG_MAX==INT_MAX).
Hay argumentos para los dos campos.
Con

matriz = malloc(n* sizeof *matriz);

nunca hay argumentos para el campo 'cast'. Este malloc siempre hace lo
que querés.
--
Horst
Antoine Leca
2005-04-04 16:48:22 UTC
Permalink
Post by Horst Kraemer
Post by Antoine Leca
Hay argumentos para los dos campos.
Con
matriz = malloc(n* sizeof *matriz);
nunca hay argumentos para el campo 'cast'.
¿ C++ ?
Post by Horst Kraemer
Este malloc siempre hace lo que querés.
En C, de acuerdo. Pero resulta que los que lo saben son los mismos que jamás
olviden de #includir <stdlib.h>...


Antoine
malory
2005-04-05 08:37:19 UTC
Permalink
bueno tienes que utilizar la formula de ziseof
Post by Fernando
Si quiero reservar de forma dinámica memoria para un vector de n
int *vector;
vector = (int *) malloc (n * sizeof(int));
¿Que debo hacer si quiero reservar memoria de forma dinámica para una
matriz de n * n elementos??
Loading...