C/Visual C - Alguien me dice que pasa aqui???

 
Vista:

Alguien me dice que pasa aqui???

Publicado por Nelek (816 intervenciones) el 20/02/2007 08:09:34
Hola, tengo el siguiente codigo (que me da problemas),

en el header
CArray <BYTE, BYTE&> p_aPrueba;

void CMyView::WritePCCode (CFile* file)
{
int nCodeLarge = 320;
p_aPrueba.SetSize (nCodeLarge);

BYTE aPrueba [320];

for (int i = 0; i < 320; i++)
{
if ( i < 256)
p_aPrueba[i] = i;

else
p_aPrueba[i] = 0;
}

const void* lpCodeBuf;
lpCodeBuf = (void*)&p_aPrueba[0];
file->Write (lpCodeBuf, sizeof (p_aPrueba));

return;
}

Con un AfxMessageBox compruebo que realmente el vector CArray del MFC tiene los elementos que pido, se rellena como toca, pero resulta que al escribir en el archivo, me escribe SOLO 20 bytes. Si conforme lo tengo, simplemente borro los "p_" y dejo que se ejecute exactamente lo mismo pero para el "BYTE Prueba [320]" entonces funciona a la perfeccion y hace lo que se supone que debe de hacer.

Por que narices con el p_aPrueba, me funciona mal y con el array de toda la vida me funciona bien?

Si pongo:

file->Write (lpCodeBuf, nCodeLarge * sizeof (BYTE));

entonces funciona bien.

No es por cuestion de funcionamiento ya que la solucion ya la tengo, es por curiosidad, porque el "sizeof (array)" funciona bien con uno y con el otro no? No lo entiendo.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Alguien me dice que pasa aqui???

Publicado por Tom (619 intervenciones) el 20/02/2007 14:18:00
No sé qué cosa es un CArray, pero si es algo parecido a un vector, deberías usar p_aPrueba.size() * nCodeLarge (o algo parecido), en lugar de sizeof.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Alguien me dice que pasa aqui???

Publicado por Tom (619 intervenciones) el 20/02/2007 14:50:09
Yo diría que tu objeto p_aPrueba de tipo CArray, ocupa 20 bytes en memoria. :-)
Ten en cuenta que este tipo de clases (Collections y demás) trabajan con punteros. El tamaño de un puntero, suele ser 4, no el tamaño de la memoria a la que apunta.

He mirado la doc, y tú necesitarías hallar el tamaño con p_aPrueba.GetSize() * sizeof(BYTE)

Por otra parte, nada te asegura que todos los elementos que has añadido a tu CArray estén en zonas contiguas de memoria.

Aparentemente, cuando haces

p_aPrueba[i] = i;

el compilador lo está traduciendo (más o menos, ya que falta ver cómo maneja el operado []) a
p_aPrueba[i] = new BYTE(i);
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Alguien me dice que pasa aqui???

Publicado por Nelek (816 intervenciones) el 20/02/2007 15:22:04
Si, algo asi me suponia, aunque "en teoria" el CArray (de las MFC para VC++), hace lo mismo que un array normal con funcionalidades anyadidas. En cuanto a lo de la memoria reservada para el CArray, precisamente por eso le digo:

p_aArray.SetSize (nCodeLarge);

con esto se reserva la memoria, es una funcion que sobrecarga los famosos malloc y demas para reserva de memoria dinamica. Supuestamente deberia ser igual.

Que los elementos estan ahi, estoy segurisimo. Me he chupado 320 MessageBox para comprobarlos, tanto al introducirlos como justo antes de escibir en el fichero.

Como ya dije, la solucion ya la habia encontrado, con la sentencia:
file->Write (lpCodeBuf, nCodeLarge * sizeof (BYTE));

Y en el caso que el "sizeof" se ralle y tome el tamanyo de los punteros... A mi me escribe 20 Bytes en el fichero y no me cuadran los numeros, por eso plantee la duda en el mensaje.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Alguien me dice que pasa aqui???

Publicado por Tom (619 intervenciones) el 21/02/2007 18:16:55
Nopi, con SetSize() le dices cuantos elementos puede contener (inicialmente), que no es lo mismo que calcular el espacio que ocupan todos los elementos.

Y, lo que te quería dar a entender, es que CArray sólo almacena punteros a objetos. Quizás todos los punteros estén en una zona contigua de memoria (un array clásico) pero los objetos apuntados estarán dispersos, casi con toda seguridad.

¿ Has probado, por curiosidad, a mirar el tamaño (con sizeof) de un CArray recien creado (antes de insertar nada) ? Habría que ver la declaración de CArray en el código fuente para ver por qué su tamaño es de 20. Esto podría ser, por ejemplo, porque contiene:
4 bytes para llevar la cuenta de elementos.
4 bytes para un puntero al array de punteros
4 bytes para indicar el primer índice válido
4 bytes para indicar el último índice válido
4 bytes para indicar el tamaño del array de punteros

(y me lo estoy inventando, pero ¿por qué no? :-))
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Alguien me dice que pasa aqui???

Publicado por fernando.gomez (1603 intervenciones) el 21/02/2007 03:32:53
Hola. No entiendo el por qué del siguiente código:

const void* lpCodeBuf;
lpCodeBuf = (void*)&p_aPrueba[0];
file->Write (lpCodeBuf, sizeof (p_aPrueba));

no entiendo la necesitad de declarar lpCodeBuf. En fin, haces que esta variable apunte al PRIMER elemento de tu CArray, la cuál por cierto es una clase, no un vector. Que internamente maneje un vector y se comporte como tal, es otra cosa, pero es una clase a final de cuentas. sizeof(p_aPrueba) te va a regresar el tamaño de esa clase eventualmente.

En todo caso, deberías poner algo como:

file->Write(&p_aPrueba[0], sizeof(BYTE));

Pero supongo que no es esto lo que quieres, ¿verad? Asumo que quieres escribir todos esos bytes a tu archivo. Pues creo que lo más fácil sería:

file->Write(p_aPrueba.GetData(), nCodeLarge * sizeof(BYTE));

Finalmente, tampoco entiendo por qué usar CArray. Si es un búfer normal, ¿no te convendría emplear char* o BYTE* ?

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Alguien me dice que pasa aqui???

Publicado por Nelek (5 intervenciones) el 21/02/2007 08:07:31
Hola fernando, gracias por contestar.

En primer lugar, lo del comando para escribir lo puse asi, porque es como lo define la ayuda del VC++ (copio lo que use):

virtual void Write( const void* lpBuf, UINT nCount );
throw( CFileException );

lpBuf
A pointer to the user-supplied buffer that contains the data to be written to the file.

nCount
The number of bytes to be transferred from the buffer. For text-mode files, carriage return–linefeed pairs are counted as single characters.

Example

//example for CFile::Write
extern CFile cfile;
char pbuf[100];
cfile.Write( pbuf, 100 );

Pero gracias por la mejora del comando, lo usare como tu me has recomendado.

En cuanto a lo de usar el CArray es porque no tengo muy claro el concepto de y el como usar los buffer.
Lo que tengo que hacer es, consultar diferentes clases para tomar datos y escribir en el archivo con una estructura muy determinada donde hay partes que son fijas y partes que dependen en valor y en numero de elementos de los datos que leo de las otras clases. Por eso elegi el CArray, para ir almacenando los datos y poder escribir comprobar las cosas antes de mandarlas al fichero. Se que no es lo optimo, pero es de lo que se manejar relativamente bien.

Se aceptan consejos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar