Título: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: dgrip en 21 Abril 2019, 18:09 pm Hola,
No sabia que poner en el titulo asi que he puesto lo que me ocurre xd. Mi problema es el siguiente: Estoy haciendo un `parseador` de json con instrucciones SSE y tal para ver si hay una diferencia notable entre indexarlos usando SSE4.2 o recorriendo arrays. El problema surge cuando tengo una variable `vv` que quiero que apunte a `v->ao + offset`. `v` es la estructura que contiene los valores de cada json, v->ao es un campo que apunta al siguiente valor del json, la estructura queda asi: Código
como se puede ver en la union esta el campo *ao, que en caso de ser un valor apuntara al siguiente. Por ejemplo el json `{ "key": "value" }, sera esto: Código
A la hora de decodificar los arrays y los objectos guardo un array de _json_value en v->ao, por tanto v->ao = malloc(sizeof(struct _json_value)*x). El puntero va cambiando el tamaño por cada valor nuevo que se inserta. Explicado el contexto... el error es el siguiente: (https://files.catbox.moe/ns6exz.png) Ocurre en la linea 209 (por eso el breakpoint ahi). v->ulen indica el tamaño del puntero de v->ao (eso esta bien), lo que no entiendo es por que v->ao + v->ulen = v->ao+3136, cuando v->ulen = 56. Por supuesto, como esto no tiene logica, el resultado del programa esta mal. Si alguien consigue encontrar el error. En cuanto al codigo... no voy a subirlo a Github de momento, asi que no se puede consultar, ya lo hare cuando vea conveniente, ahora no esta decente. Gracias. Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: MAFUS en 21 Abril 2019, 18:38 pm ¿Qué tal si pones el código real de la carga de las dos estructuras (externa e interna)?
Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: dgrip en 21 Abril 2019, 18:43 pm ¿Qué tal si pones el código real de la carga de las dos estructuras (externa e interna)? No se a que te refieres exactamente, si lo puedes preguntar de manera mas extensa... xd Si te refieres a _json_value, tanto v como v->ao son la misma estructura. De todas formas te pongo la funcion que hace esta operacion (que estoy debuggeando) Código
(https://files.catbox.moe/kgn3a5.png) Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: MAFUS en 21 Abril 2019, 18:51 pm No tendría que ser así?
Código: #define INCR(x) x+=sizeof(json_value); Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: dgrip en 21 Abril 2019, 18:55 pm No tendría que ser así? Código: #define INCR(x) x+=sizeof(json_value); Si, perdona, me he confundido escribiendo. De todas formas el fallo no está ahi Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: dgrip en 21 Abril 2019, 23:56 pm Código: [code] Al parecer C es de tan alto nivel que cuando sumas un puntero que tiene una estructura definida (como pasa con _json_value) lo que hace es sumarlo en funcion del numero que le pasas, por tanto: sizeof(_json_value) = 56; _json_value += 2 = sizeof(json_value) * 2; Vaya, que se soluciona poniendo `v->ao += v->ulen/sizeof(json_value)` o `v->ao += ((void *)v->ao) + v->ulen[/code] Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: RayR en 22 Abril 2019, 03:23 am Ojo, que usar la segunda forma:
Código: ((void *)v->ao) + v->ulen es riesgosa. Tanto en C y C++ no es válido efectuar aritmética de punteros con punteros void. Aunque algún compilador pueda permitirlo, no hay garantía de que siempre funcione, y es el tipo de cosas con las que los compiladores frecuentemente rompen compatibilidad. Para avanzar por un puntero en términos de bytes, mejor hacer el cast a puntero char, que es legal en C/C++. Título: Re: Direccion de memoria + numero != Direccion de memoria esperada Publicado por: dgrip en 22 Abril 2019, 12:55 pm Ojo, que usar la segunda forma: Código: ((void *)v->ao) + v->ulen es riesgosa. Tanto en C y C++ no es válido efectuar aritmética de punteros con punteros void. Aunque algún compilador pueda permitirlo, no hay garantía de que siempre funcione, y es el tipo de cosas con las que los compiladores frecuentemente rompen compatibilidad. Para avanzar por un puntero en términos de bytes, mejor hacer el cast a puntero char, que es legal en C/C++. Aunque pueda no aplicarse a todos los compiladores que se van a usar (xd) tienes razon, usare mejor `char`. |