problema con struct

Started by master, December 28, 2012, 07:35:04 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

master

Hola de nuevo

Estoy trabajando con unas cuantas struct's, y el programa en ciertas partes tiene un comportamiento peculiar, o mas bien, muy extraño.
Lo explicaré de esta manera:

Tengo declaradas las siguientes estructuras:

STRUCT page_act
        string dialogo[9];
        int lineas;
        int linearespuesta[2];
        int respuestas;
        string respuesta[5][2];
        string titulo;
        string descripcion;
    END
     
    STRUCT vnt_act
        int imagen;
        string musicpag;
        string soundpag;
        string scrollpag;
        string animpag;
        int numanimpag;
        string fadepag;
    END
     
    STRUCT vnt_sig
        int imagen;
        string musicpag;
        string soundpag;
        string scrollpag;
        string animpag;
        int numanimpag;
        string fadepag;
    END


Caso peculiar Numero 1:

cuando uso "memcopy(&vnt_act,&vnt_sig,sizeof(vnt_sig));", para copiar el contenido de una estructura a otra y despues en algun momento del codigo le asigno al registro "vnt_sig.animpag" algun valor cualquiera (incluso igual al que tenia antes), y despues solicito el valor de "vnt_act.animpag": ME CRASHEA DICIENDO: Violación de segmento (`core' generado)
NOTA 1: esto solo sucede con el registro "vnt_act.animpag" y "vnt_sig.animpag", con ningún otro registro sucede eso.
NOTA 2: Si en vez de usar "memcopy", asigno registro por registro (vnt_act.XXXX=vnt_sig.XXXX) funciona bien.

Caso peculiar Numero 2:

estoy haciendo un incremento de 1 en 1 al registro (inicializado a 0) "page_act.lineas", y de pronto, despues de llegar a 10 e intentar incrementar una vez mas, nunca llega a 11, sino a un numero aleatorio entre 4100 y 4200.

Y una pregunta mas:
¿Un DBC generado en linux funciona en windows, o tengo que compilar en windows?
lo pregunto porque un día por error tomé el DBC de una versión linux y la corrí en windows, pero el único problema que tuve fue de visualización, ya que no me tomaba la resolución que yo le definía, sino la de mi escritorio.

SplinterGU

seguro, no puedes hacer memcopy de estructuras con datos string.

prueba hacer

vnt_act = vnt_sig;

aunque siendo de diferente tipo no se si funcionara.

deberias declarar un tipo de dato, y luego usar ese dato para definir variables, y ahi podrias hacer vnt_act = vnt_sig; sin problemas.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

master

#2
Quote from: SplinterGU on December 28, 2012, 03:23:12 PM
seguro, no puedes hacer memcopy de estructuras con datos string.

prueba hacer

vnt_act = vnt_sig;

aunque siendo de diferente tipo no se si funcionara.

deberias declarar un tipo de dato, y luego usar ese dato para definir variables, y ahi podrias hacer vnt_act = vnt_sig; sin problemas.

Segun el manual de OSK; si uso "vnt_act = vnt_sig" habrá error. Cito a la biblia:

Quote from: Manual de OSK
...
process main()
private
   struct struct1
      Int c;
      Int d;
   end =1,4;
   struct struct2
      Int c;
      Int d;
   end
end
begin
//Las estructuras han de ser idénticas en lo que se refiere a no,tipo y orden de campos
struct2=struct1;
//Copio los valores de los campos de struct1 a struc2
...


Bien. Si intentamos ejecutar esto el intérprete nos devolverá un error en la línea donde se supone que copio
el contenido de struct1 a struct2.
Parece pues que no se hace así la copia...

Copiar tablas o estructuras no es tan fácil como copiar valores entre variables simples.Para lograr hacerlo
correctamente, necesitamos hacer uso de la función memcopy(), definida en el módulo "mod_mem"...
Entonces casi me queda claro: no se puede hacer memcopy con estructuras con datos string (como dijiste).
Lo que pasa es que si me hace la copia con memcopy, el problema es cuando después del memcopy le intento asignar un valor distinto a la variable de origen(osea, reutilizarla).

No pense que memcopy no funcionara, ya que entonces ¿que sentido tiene si también se pueden declarar estructuras con datos string?
Como escribí antes: si asigno registro por registro (osea, si uso vnt_act.animpag=vnt_sig.animpag;) si me funciona.

¿Entonces para solucionarlo tendré que declarar un tipo de dato?

Es que se me hace mas cómodo usar struct porque si uso type, solo crearía 2 variables con este Type, y no vale la pena ya que son para usos muy distintos.

quisiera seguir usando Struct, pero también me sucede esto:

Estoy haciendo un incremento de 1 en 1 al registro (inicializado a 0) "page_act.lineas", y de pronto, después de llegar a 10 e intentar incrementar una vez mas, nunca llega a 11, sino a un numero aleatorio entre 4100 y 4200.

SplinterGU

type no crea variables, solo crea un tipo de dato, luego tu creas la variable usando ese tipo.

si quieres usar datos del estilo string dentro de un struct usa char en lugar de string.... por ejemplo.

TRUCT page_act
        char dialogo[9][30];
        int lineas;
        int linearespuesta[2];
        int respuestas;
        char respuesta[5][2][30];
        char titulo[50];
        char descripcion[128];
    END

ahi ves que el di 30 caracteres maximo a las 2 primeras
50 a titulo
128 a descripcion

y ya usas eso tranquilamente con memcopy....

con respecto a struct1 = struct2; antes no se podia hacer, ahora se puede hacer... pero como te repito, creo que solo de datos del mismo tipo o datos que tienen los mismos tipos de elementos internamente... o sea, puede que si las 2 structs son iguales lo permita copiar... pero no lo recuerdo... pero lo que si estoy seguro es que si son 2 variables del mismo type, funciona perfectamente.

pruebalo y me cuentas.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

eso de los 4200, pon un ejemplo que pueda compilar... asi no entiendo que quieres decir.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

master

Ok, este es una muestra con el mismo comportamiento:
Antes que nada:

Recuerdas que te decía lo de 4200:
En este ejemplo cambié los string por char para ver que cambios habia; resuta que cuando tiene un string el numero que arroja (que pensaba yo era aleatorio) es de 40 a 60, y con char ahora es 1835081802!!. Esto es a lo que me refiero con lo del 4200.

Si saco del struct el string o el char y la estructura solo tiene un tipo de dato (es este caso int) funciona bien y sigue contando normalmente, aun asi, yo creo que no debería haber problemas, pienso que es un error.

Este es el código del main

import "mod_key";
Import "mod_video";
Import "mod_text";
Import "mod_map";
Import "mod_screen";
import "mod_string";
import "mod_file";
import "mod_debug";
import "mod_say";
import "mod_debug";

#include "jkeys.lib"

Global
    int archivo;
    STRUCT page_act
        char dialogo[9][31];
        int lineas;
    end
    int pack1;
    int nivel=1;
end

include "cargar_texto.prg";

process main()
begin
    set_mode(1200,240,16);
    jkeys_set_default_keys();
    jkeys_controller();
    cargar_dialogotxt();
    imprime_texto();
    set_fps(60,1);
    pack1=load_fpg("shpn1.fpg");
    LOOP
        SWITCH(nivel)
            CASE 1:
                put_screen(pack1,1);
                frame(10000);
                put_screen(pack1,2);
                frame(10000);
                put_screen(pack1,3);
                frame(10000);
                nivel=2;
            end
            case 2:
                if(jkeys_state[_JKEY_MENU])
                    let_me_alone();
                    exit();
                end
                frame;
            end
        end
    end
end


este es el contenido de "cargar_texto.prg"

process cargar_dialogotxt()
private
    char lineatemp[31];
    int lineaactual=0;
    int i;
end
begin
    page_act.lineas=0;
    archivo=fopen("harry0p.lng",O_READ);
    lineatemp=fgets(archivo);
    while (feof(archivo)!=true)
        if(lineatemp!=chr(43))
            page_act.dialogo[lineaactual]=lineatemp;
            page_act.lineas+=1;
            say(page_act.lineas);
            say(lineatemp);
            say(page_act.dialogo[lineaactual]);
            lineaactual++;
            debug;
        end
        lineatemp=fgets(archivo);
    End
end

process imprime_texto()
private
    int i;
    int lineaactual;
    int saltar=0;
end
begin
    for(lineaactual=0; lineaactual<page_act.lineas; lineaactual++)
        For(i=0; i<=len(page_act.dialogo[lineaactual]); i++)
                write(0,10+14*i,(lineaactual+1)*30,0,page_act.dialogo[lineaactual][i]);
            if(jkeys_state[_JKEY_X])
                saltar=1;
            end
            if(saltar ==0)
                if(page_act.dialogo[lineaactual][i]==chr(46))
                    frame(1000);
                else
                    frame;
                end
            end
            if(page_act.dialogo[lineaactual][i]==chr(46))
                saltar=0;
            end
        End
        frame;
    End
end


y como texto ("harry0p.lng") puedes usar cualquier texto que sobrepase las 11 lineas y al final del mismo halla un signo de "+"

It's been a while since I have
taken a vacation. I am driving
my jeep. Heading towards the
quiet resort town of Silent
Hill, the sound of the engine
reverberates in the darkness.
Due to some slight car trouble
earlier, it has become this
late.

I am Harry Mason.
I am a run of the mill writer.
+


Coloque un debug y unos say, al llegar a 10 el numero que arroja es 1835081802, y despues se conjela.

SplinterGU

claro, si tienes solo 10 elementos char (de 0 a 9 inclusive) y quieres cargar mas que eso.

obviamente cuando quieras cargar el numero 10 u 11 o cualquier otro, reventara todo por los aires... con suerte dara valores extraños y no reventara... pero lo mas probable es que reviente.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

master

 :o
Ouch, no me di cuenta de eso...
puff...
No me di cuenta de algo que yo mismo hice, le puse como limite que solo pudiese almacenar 10 lineas y le pido que almacene 12.
jejejeje
Gracias por soportarme.
Creo que la única duda que valió la pena fue lo de memcopy (sirvió como aclaración y retroalimentación)
Vale... Manos a la obra. :D

SplinterGU

Download Lastest BennuGD Release: http://www.bennugd.org/node/2