C ++ 클래스의 실제 크기를 어떻게 찾을 수 있습니까?
문제
나는 문자열과 qsort/bsearch 대신 숯 배열을 사용해야하는 숙제 할당을 연구하고 있습니다. 아래에서 bsearch에 대한 나의 부름에서, i 알다 입력의 잘못된 크기를 전달하지만 실제 크기를 얻는 방법을 잘 모르겠습니다. 따라서 ComparentRies 기능은 올바른 개체를 찾지 못합니다.
누구든지 내가 놓친 것을 이해하도록 도와 줄 수 있습니까?
#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;
}
해결책
왜 그렇지 않습니다 sizeof(Entry)
일하다?
다시 변경 - 크기가 포인터의 크기라고 생각합니다 ....
EntryPtr tmp = new Entry("");
tmp->Word = word;
EntryPtr result = (EntryPtr) bsearch(tmp, m_entries,
m_numEntries, sizeof(EntryPtr), Dictionary::compareEntries);
다른 팁
문제는 비교 기능이 사용된다는 것입니다 bsearch
기대합니다 word
유형이 될 수 있습니다 Entry*
(또는 m_entries
유형이 될 수 있습니다 char**
).
당신은 그것을 알고 있습니다 bsearch
정렬 된 입력이 필요합니까?
sizeof(m_entries[0])
나에게 완벽하게 좋아 보인다.
편집 : 이제 문제가 있습니다. 사전 클래스에는 다양한 포인터가 포함되어 있습니다. 문제는 Compareentries 기능에있어서 전달 된 포인터를 EntryPtr
; 당신은 그들을 던져야합니다 EntryPtr *
대신에.
편집 2 : 지적한대로 Amit Kumar, 너 또한 BSEARCH에 보내는 주요 매개 변수를 변경해야합니다. 그렇지 않으면 ComparentErries에서받는 포인터가 동일한 유형을 가리키지 않으며 두 개의 다른 타입 캐스트가 필요하다는 것을 알아야합니다.
크기 (Entry)의 크기가 작동합니다. 인스턴스 대신 유형에서 대부분 Sizeof를 사용해야합니다.
Sizeof (Entry)
바람직합니다
입력 E;
크기 (e);
또는
진입* e;
크기 (*e);
모두 같은 결과를줍니다.
#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;
}
읽기 수동 주의하여.
다른 사람이 만든 요점에 대한 요약과 몇 가지 더 많은 문제가 있습니다.
귀하의 사용법 크기 맞다.
찾아보고 싶은 키가 포함 된 항목에 대한 포인터를 전달해야합니다.실제로 열쇠는 무엇이든 될 수 있으며, 첫 번째 인수로서 비교 함수로 전달되며, 두 인수를 올바른 유형에 시전하면됩니다. (비교 함수는 여전히 항목이 정렬 한 순서에 해당해야합니다.)비교 함수의 캐스트는 올바르지 않습니다. 비교 함수는 요소에 대한 포인터를 수신합니다 (귀하의 경우 입력에 대한 포인터이므로 비교 함수는 입력 포인터에 포인터를받습니다).
결과를 잘못된 유형으로 시전합니다. 다시 함수는 배열의 요소에 대한 포인터를 반환합니다 (입력 포인터에 대한 포인터).
키가 없으면 결과가 null인지 확인하지 않습니다.
당신은 아마도 한 수준의 간접 수준을 포기할 수 있습니다 (실제로 항목 배열 대신 많은 포인터가 필요합니까?)
당신은 사람들이 유형 안전의 미덕에 대해 이야기 할 때 의미하는 바에 대한 좋은 예로 받아야합니다. 코드에서 거의 모든 유형이 혼합되고 잘못된 유형으로 잘못된 일을하고 있지만 단일 불만은 아닙니다. 컴파일러. 그게 당신이 엉망이면 당신이 얻는 것입니다
void*
, 당신이 무엇을하고 있는지 정확히 알지 못한다면.
재미를 위해, 많은 포인터 배열을 갖는 것은 결과를 얻기 위해서는 말도 안되는 양의 간접이 필요합니다.
#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';
}
IMO,이 모든 것을 파악하고 테스트하고 디버깅하는 데 걸리는 것보다 자신의 유형-안전 BSEARCH를 구현하는 데 시간이 덜 걸립니다.