¿Cómo puedo encontrar el tamaño real de mi clase de C ++?
Pregunta
Estoy trabajando en una tarea en la que yo estoy obligado a utilizar matrices de char en lugar de cuerdas y qsort / bsearch. En mi llamado a bsearch a continuación, I saben que estoy pasando el tamaño incorrecto de entrada, pero no estoy seguro de cómo obtener el tamaño real, y mi función compareEntries por lo tanto, no es encontrar los objetos adecuados .
Puede alguien ayudarme a entender lo que me falta?
#include <iostream>
using namespace std;
typedef Entry* EntryPtr;
class Dictionary
{
public :
Dictionary( const char *filename );
~Dictionary();
const char *lookupDefinition( const char *word );
private :
int m_numEntries;
EntryPtr *m_entries;
static int compareEntries(const void *leftSide, const void *rightSide);
};
int Dictionary::compareEntries(const void *leftSide, const void *rightSide)
{
EntryPtr lside = (EntryPtr) leftSide;
EntryPtr rside = (EntryPtr) rightSide;
return strcmp(lside->Word, rside->Word);
}
const char *Dictionary::lookupDefinition(const char *word)
{
if (m_numEntries == 0)
return 0;
EntryPtr result = (EntryPtr) bsearch(word, m_entries,
m_numEntries, sizeof(m_entries[0]), Dictionary::compareEntries);
return result->Definition;
}
class Entry
{
public:
Entry(const char *line);
char *Word;
char *Definition;
};
int main()
{
Dictionary dict( "C:\\path\\file.txt" );
dict.lookupDefinition("chair");
return 0;
}
Solución
¿Por qué no sizeof(Entry)
trabajo?
cambió de nuevo - Creo que el tamaño debe ser el tamaño del puntero ....
EntryPtr tmp = new Entry("");
tmp->Word = word;
EntryPtr result = (EntryPtr) bsearch(tmp, m_entries,
m_numEntries, sizeof(EntryPtr), Dictionary::compareEntries);
Otros consejos
El problema es que la función de comparador utilizado en bsearch
espera word
a ser de tipo Entry*
(o m_entries
a ser de tipo char**
).
Se hace saber que bsearch
requiere una entrada ordenada, ¿verdad?
sizeof(m_entries[0])
se ve perfectamente bien para mí.
Edit: Ahora veo el problema. Su clase Dictionary contiene una matriz de punteros. El problema está en la función compareEntries, donde pasó elenco punteros a EntryPtr
; que necesita para echarlos a EntryPtr *
lugar.
Editar 2: Como se ha señalado por Amit Kumar , también necesidad de cambiar el parámetro clave que envíe a bsearch, o si tiene que darse cuenta de que los punteros que se reciben en compareEntries no están apuntando a los mismos tipos y necesitará dos typecasts diferentes.
sizeof (Entrada) funcionaría. Parcialmente sizeof se debe utilizar en el tipo en lugar de una instancia.
sizeof (Entrada)
es preferible
Entrada electrónico;
sizeof (e);
o
Entrada * e;
sizeof (* e);
todos dan el mismo resultado.
#include "stdio.h"
class Entry {
double e;
int i;
};
int main() {
Entry e;
printf("%d\n", sizeof(e));
printf("%d\n", sizeof(Entry));
printf("%d\n", sizeof(*(&e)));
return 0;
}
rel="nofollow cuidado.
Un resumen de las observaciones hechas por otros, así como un par de cuestiones:
-
Su uso de sizeof es la correcta.
-
Usted debe pasar un puntero a la entrada que contiene la clave que desea buscar.En realidad, la clave puede ser cualquier cosa, y se pasa a la función de comparación como el primer argumento y sólo tiene que echar a ambos argumentos tipos correctos. (La función de comparación debe todavía corresponder al orden los artículos fueron ordenados por.) -
Los moldes en la función de comparación no son correctos. La función de comparación recibe un puntero al elemento (que en su caso es un puntero a la entrada, por lo tanto, la función de comparación recibe punteros a punteros a la entrada).
-
Lanzas el resultado al tipo equivocado. De nuevo, la función devuelve un puntero a un elemento de la matriz (puntero a puntero a la entrada).
-
No comprueba si el resultado es NULL, la clave no debe estar allí.
-
Probablemente se podría renunciar a un nivel de indirección (lo que realmente necesita una matriz de punteros en lugar de una serie de entradas?)
-
Usted debe tomar como un buen ejemplo de lo que la gente quiere decir cuando hablan de las virtudes de la seguridad de tipos: en su código de prácticamente todos los tipos se mezclan y que está haciendo cosas mal con mal tipos, sin embargo, ni una sola queja de que el compilador. Eso es lo que se obtiene si se metan con
void*
, a menos que sepa exactamente lo que está haciendo.
Para el gusto de hacerlo, tiene un conjunto de punteros se necesita una cantidad ridícula de indirección para obtener un resultado:
#include <cstdlib>
#include <string>
#include <iostream>
int compare_string(const void* a, const void* b)
{
return ((const std::string*)a)->compare(**(const std::string**)b);
}
int main()
{
std::string a("a"), b("b"), c("c");
std::string* array[3] = { &a, &b, &c };
std::string key = "b";
std::string** result = (std::string**)bsearch(&key, array, 3, sizeof(std::string*), compare_string);
if (result) std::cout << **result << '\n';
}
OMI, tomaría menos tiempo para implementar su propio bsearch de tipo seguro, que se necesita para entender todo esto y lo han probado y depurado.