클래스의 변수는 메모리에 순차적으로 저장이 되나요??

oneclubs의 이미지

암호화를 공부하다가
간단하게 해보자 하다가 일이커졌네요..
두 클래스가 있습니다.

class high{
public :
	int flags;
	int size;
};
 
class low : public high{
public:
	int value1;
	int value2;
	int value3;
};
 
class crypt : public high{
public :
	char *data;
};

보시면 아시겠지만 high에 상속된 low와 crypt클래스가 있습니다..
high에서 상속되는 여러클래스를 죄다 crypt로 변환해서 data에 변환값을주고 다시 원래 클래스로 돌려서 암호화를 하려 하는데요
하다보니 이상한게..
class변수는 메모리에 순서대로 들어가는게 아니었나요!?!
low temp;라고 선언하면..
temp의 주소가 1000 이면 1000에 value1, 1004에 value2, 1008에 value3이렇게 들어가는게 아닌가요?

low클래스는 12바이트니까
crypt의 data를 12바이트로 잡은다음에 때려넣으면 들어갈줄 알았는데
안들어갑니다 어흑그그흐그흐

low temp; temp.value1 = 15; temp.value2 = 22; temp.value3=44;라고 하고..
crypt cr; cr.data = new char[12];
한담에 memcpy(cr, &temp , 12); 이렇게 하니까.. value1값만 cr로 가더라구요..(다른 low인스턴스에 복구시켜보니)

그래서 memcpy말고
이렇게..
cr.data = (char *)&temp;
해보면 얼추 가는거 같은데 거꾸로가 잘 안됩니다.
low temp2 여기에 cr.data를 거꾸로 어떻게 집어넣느냐 이게 문제죠..
이게 안되니까 cr.data = (char *)&temp;이것도 의도대로 진행되었는지도 모르겠구요..

오버로딩으로 해결해보면 어떻게 어떻게 될수도 있을꺼 같은데 그러면 모든 high를 상속받은 클래스에 대해 crypt는
= 연산자 오버로딩을 만들어야하고..그러기엔 너무 귀찮고 'ㅡ' 메모리로 어떻게 해결하고 싶은데..
좋은 방법이 없을까요?

아니 왜 그걸 굳이 char*로 때려넣느냐? 라고 물으시면
high에서 상속받는 모든 클래스를 crypt클래스로 때려넣고
crypt에 키값과 xor걸어서 다시 decrypt하려는게 목적이거든요..

bootmeta의 이미지

...

klara의 이미지

암호화 자체에 대해서는 전혀 모릅니다만, 몇가지만 적어보면..
우선 low는 12바이트가 아닙니다. 실제로 sizeof 해보셨나요? 정렬문제를 제외하더라도 최소한 20바이트입니다.
그리고 클래스의 복사를 memcpy로 하는것은 위험합니다. 특히나 예제로 드신거처럼 상속이 껴있을경우는 더욱 그러합니다.마지막으로 적으신 코드는 상속을 하고 있음에도 불구하고 소멸자가 가상함수가 아니기 때문에 동적바인딩을 이용할 경우 메모리 누수가 일어날수 있습니다.
PS 중복등록된 다른 글은 삭제해주세요.

netionics의 이미지

정렬제한, 패딩, 가상 함수 유무, 가상 상속 유무, 각 멤버에 붙은 접근 제한자 등등 신경 써야 할 것이 한 두가지가 아닙니다.
신경 쓴다고 해결되지도 않을 겁니다. 다른 방식을 쓰는게 건강을 위하는 길입니다.

:)

oneclubs의 이미지

중복글은 지웠습니다. 중복이 되어있었는지도 몰랐네요 ㅠ 코드보다 정신줄을 놓아버려서 글올리고 기절했다가 일어났네요

네 당연히.. low크기는 20바이트라는건 아는데요.. 상속된 부분만 볼때 12바이트라 이말이었는데 글을 쓰고보니 대체 머라고 쓴건지 ㅋ
상위 클래스가 8바이트가 있고..
상속된 low의 클래스는 8+12니까..
상속된 crypt클래스에 8+12로 맞춰주고 low의 12를 crypt 12로 복사하고자 저런 뻘짓거리를 하고 있거든요.. 'ㅡ'
소멸자나 머 이런문제는 다 재껴놓고 생각하려다보니 힘드네요..

패딩문제는 어떻게해서든.. 때려맞출까 생각중입니다.. 말은 쉽지만.. ㅠ

어떻게 해서든 클래스를 죽어도 써야한다면 방법이 없을까요..

bootmeta의 이미지

padding을 1로 했다치더라도 C++인 경우 내부적으로 각 instance 별 할당된 memory 크기와 구조가 컴파일러마다 천차만별입니다. (심지어 같은 컴파일러일지라도 버전따라 틀려질 수 있습니다.)

예를 들어
1) 가상함수 삽입 시 각 instance 마다 보이지 않는 vtable 생성
- 아마 가상 함수가 없으면 없으리라 생각됩니다만, 모든 컴파일러가 보장하는지는 모르겠군요.
2) 예를 드신 경우는 아닙니다만, multi 상속을 받는 경우, member function pointer 크기가 가변이거나(vc++), 12(16? 가물 가물)바이트인가?(gcc)일 수도 있습니다.

3) debug 모드나 compiler option에 따라 instnace에 숨겨진 정보가 있을 수 있습니다.

4) source 상 instance member가 순서대로 memory에 있다는 보장이 없습니다.(아마도? 이건 저 자신도 좀 애매하군요. --;)

5) 그 외 또다른 요인이 있을지 모르겠습니다. C++ 해본지 하도 오래되서 가물 가물...

C라면 모를까, C++이라면 처음부터 저런 방법 구현은 안하는게 속 편하실 것 같군요.
굳이 사용하시겠다면 일단 사용 컴파일러나 컴파일 설정부터 정보 공개하시면 다른 분이 도움을 주실지도...

netionics의 이미지

Quote:

4) source 상 instance member가 순서대로 memory에 있다는 보장이 없습니다.(아마도? 이건 저 자신도 좀 애매하군요. --;)

class widget {
private: int first;
private: int second;
private: int third;
};

접근제한자를 멤버마다 붙이면 컴파일러가 순서를 맘대로 정할 수 있습니다.

:)

bootmeta의 이미지

POD struct에 대한 다음 문서를 참고 하시는 것이 도움이 될 겁니다.
http://en.wikipedia.org/wiki/C%2B%2B_structure#POD-structs
http://www.comeaucomputing.com/techtalk/#pod

an aggregate may not contain any user-defined constructors, base classes, virtual functi ons, or private/protected non-static data (so it may contain private/protected static member data/functions). 

POD style 구조체는 다음 항목 포함 금지(may - 컴파일러 의존적인듯)
* 일단 사용자 정의 constructor
* base class
* virtual function들
* private/protected member data(static인 경우 가능)

* 그외 특성들

    * The storage for a POD must be contiguous.
    * If X and Y are POD-structs, and their members are of the same number and order of layout compatible types, then X and Y are layout compatible. (This is as with C).
    * If X and Y are POD-structs, and their initial members are of the same number and order of layout compatible types, then if a union containing them contains an object of either type X or Y, then it may use the respective member from either X or Y. (This is as with C).
    * A POD-struct may not have padding before its first member. (This is as with C.)
    * A pointer to a POD-struct, say X, may be converted to a pointer to some type, say T, if T is the first member of X. Said conversion should occur through a reinterpret_cast. The opposite (converting a pointer to T to a pointer to X) is also allowed. (This is as with C.)
    * The offsetof macro from <cstddef> may only be used with POD-struct or POD-union types. (This is as with C.)
    * It follows from above that a POD-class is a POD-struct (or a POD-union).
    * Yes, even built-in types such as int are POD types. This also includes normal pointers and enum's. (Pointers to members are not PODs, as this is considered a defect in the Standard.)
    * Arrays of POD types are still PODs.
    * const or volatile qualified PODs are still PODs.
    * PODs with constant initializers and static storage duration get initialized before objects (POD or otherwise) requiring dynamic initialization.
    * If it wasn't clear from the above, a POD-struct can contain static members.
    * A POD-struct can contain typedefs, nested types, member functions, friends, and this-is-all-I-can-think-of-at-the-moment. 
oneclubs의 이미지

이거 그냥 한번하자고 한일이 죽자고 커져버렸군요.. 'ㅡ' 어쩌다가 ㅠ

밤새 고민해봐도 여러가지 충돌도 많고 어휴..답변주신분들께 정말 감사드립니다..
다른방법을 고민해봐야겠네요..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.