Pregunta de C
rodrigo ahumada
rodahummont en yahoo.com.ar
Mar Mayo 9 21:00:09 CLT 2006
On Tue, 9 May 2006 20:07:10 -0400
Alvaro Herrera <alvherre en alvh.no-ip.org> wrote:
> [Republicando desde la lista oss-devel en listas.ubiobio.cl]
>
> Tengo una duda. Supongase la funcion siguiente:
>
> void
> pgr_formtuple(Relation foo)
> {
> int natt = foo->natts;
> char arr[natt];
> char nulls[natt];
>
> ...
> }
>
> Se aprecia que las variables arr y nulls son creadas como arreglos del
> tamaño especificado que no es constante en tiempo de compilacion, sino
> que se determina en tiempo de ejecucion dependiendo del contenido del
> struct Relation.
>
> Es valido esto? Debo mencionar que compila perfectamente sin ningun
> warning (con varias opciones -W), y que funciona perfectamente para
> algunos valores de foo->natts. Sin embargo, el programa se cae en un
> caso muy particular que es cuando foo->natts es 61, un valor superior a
> los valores tipicos. (natts es el numero de columnas de una tabla; por
> lo tanto 61 es un valor perfectamente valido pero tipicamente los
> valores andan cercanos a la veintena).
[...]
yo hice este codigo:
#include <stdio.h>
void rareza(int valor) {
char rareza1[valor];
char rareza2[valor];
printf("tamaño rareza 1: %d\n", sizeof(rareza1));
printf("tamaño rareza 2: %d\n", sizeof(rareza2));
int i;
for (i = 0; i < valor; i++) {
rareza1[i] = 'A';
rareza2[i] = 'Z';
}
rareza1[valor - 1] = 0;
rareza2[valor - 1] = 0;
printf("%s\n", rareza1);
printf("%s\n", rareza2);
printf("--------\n");
}
int main(int argc, char *argv[]) {
int k, desde, hasta;
if (argc == 3) {
sscanf(argv[1], "%d", &desde);
sscanf(argv[2], "%d", &hasta);
}
else {
desde = 10;
hasta = 65;
}
for (k = desde; k < hasta + 1; k++) rareza(k);
printf("adios\n");
return(0);
}
y al ver el .s que sale:
(lo estuve siguiendo un poco, no se si lo hice bien, pero se nota que en la funcion rareza,
en dos partes se guardan bytes en el stack segun el valor de [ebp+8] (valor))
...
...
.globl rareza
.type rareza, @function
rareza:
push %ebp
mov %ebp, %esp
push %ebx
sub %esp, 36 ; reserva 36 bytes en el stack
mov DWORD PTR [%ebp-12], %esp ; guarda el tope del stack dentro de esos 36 bytes
mov %edx, DWORD PTR [%ebp+8] ; edx = valor
lea %eax, [%edx+15] ; eax = valor +15
add %eax, 15 ; eax = valor + 15 +15
shr %eax, 4 ; eax = (valor + 15 +15) / 16
sal %eax, 4 ; eax = ((valor + 15 +15) / 16) * 16 ¿?
sub %esp, %eax ; reserva EAX bytes mas en el stack
lea %eax, [%esp+8] ; eax = 8 bytes antes del tope del stack
add %eax, 15 ;
shr %eax, 4
sal %eax, 4
mov DWORD PTR [%ebp-16], %eax
mov %ebx, DWORD PTR [%ebp+8] ; esto es como lo mismo de arriba...
lea %eax, [%ebx+15]
add %eax, 15
shr %eax, 4
sal %eax, 4
sub %esp, %eax
lea %eax, [%esp+8]
add %eax, 15
shr %eax, 4
sal %eax, 4
mov DWORD PTR [%ebp-20], %eax
mov DWORD PTR [%esp+4], %edx
mov DWORD PTR [%esp], OFFSET FLAT:.LC0
call printf
mov DWORD PTR [%esp+4], %ebx
mov DWORD PTR [%esp], OFFSET FLAT:.LC1
call printf
mov DWORD PTR [%ebp-8], 0
...
...
el programa lo he probado con numeros mas grandes que 61 y no se me ha caido...
de todas formas, al compilar da ni una queja, y alojar memoria el el stack
segun el valor de una variable... (!)
___________________________________________________________
1GB gratis, Antivirus y Antispam
Correo Yahoo!, el mejor correo web del mundo
http://correo.yahoo.com.ar
Más información sobre la lista de distribución Linux