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