2009. 4. 10. 13:31

구조체와 typedef의 관계

typedef struct {
int afield;
BPTR bpointer;
} * APTR;
typedef struct {
int bfield;
APTR apointer;
} * BPTR;

BPTR, APTR에 대한 typedef문제이다. 구조체는 자기 자신에 대한 포인터를 포함할 수 있기 때문에

struct a {
int afield;
struct b *bpointer;
};
struct b {
int bfield;
struct a *apointer;
};

요런 식으로 바꾸어 주면 된다. 아직 struct b를 모르지만 컴파일러는 imcomplete 구조체로 보고 허용을 해준다.
또한 때때로 struct b;  먼저 선언해 주는 것이 필요하다.
만일 BPTR, APTR를 이용하고 싶다면

typedef struct a *APTR;
typedef struct b *BPTR;

struct a {
int afield;
BPTR bpointer;
};
struct b {
int bfield;
APTR apointer;
};

요렇게 쓰면 된다.
2009. 4. 10. 13:19

Typedef과 #define(매크로)의 차이

아주 간단한 차이만 설명하겠습니다.

typedef char *String_t;
#define String_d char *

String_t s1, s2;
String_d s3, s4;

s1, s2, s3는 char*형이지만 s4는 char형입니다.

일반적으로 char *s3, s4와 같은 의미로 보고 생각하시면 됩니다.

typedef는 스코프 규칙을 잘 따르는 장점이 있고, 매크로는 #ifdef를 쓸 수 있다는 장점이 있습니다.
잘 판단해서 이용해야 겠죠? ㅎㅎ

2009. 4. 10. 11:12

int, int16, int32


C언어가 사이즈에 대한 정확한 정의 없이 typedef를 통해 제공하기 때문에 정확한 사이즈를 제어하기 위해
int16, int32를 명시하여 쓰는 경우가 많다. 하지만 int16, int32를 쓰는 목적이 적어도 이만큼의 크기를 보장하기
위해 쓰는 것이라면 전혀 의미가 없다. int정의 자체가 적어도 16bit 또는 32bit를 뜻하기 때문이다.

어느 사이즈가 고정된 특정 시스템에서 가독성이나 정확한 size제어가 필요하다면(Shift 사이즈 고정 연산이나...) 쓰는 것이 괜찮겠지만, 일반적인 경우는 의미가 없고 자칫 int와 int32가 혼동되어 사용되어 가독성이나 프로그램의 호환성, 안정성이 오히려 떨어질 수 있다.

프로그램의 특성을 잘 계획하고 판단하여 쓰는 것이 바람직 하겠다.
2009. 4. 10. 10:35

extern 선언에 대한 컴파일러의 인식과 링크

요즘에 코딩을 한지 너무 오래되서 적을 만한게 없다..ㅡㅡ;;;
애들 코드리뷰를 하면서 보았던 문제점에 대해 적어 보련다.ㅎㅎ


extern는 다른 파일에 선언되어 있는 전역변수에 대한 링크 시킨다는 의미이다.

extern 변수 선언시 변수의 타입을 기입하지 않는 경우가 있는데 이때 컴파일러는 type checjing작업을 통해
묵시적으로 사용된 값에 대한 타입을 예상하게 된다. 이는 곧 타입에 대한 기재가 없어도 심볼테이블을 통해
변수의 타입을 알아낸다는 의미가 되겠다.
하지만 만일 묵시적으로 선언된 변수가 외부에서 두가지 이상의 타입으로 선언되어 있다면 컴파일러가
어느 타입인지 추론하는게 어렵기 때문에 Link시 에러가 날 가능성이 있는 것이다.

많은 사람들이 extern 키워드를 이용하면 따로 변수를 선언하여 메모리를 잡는다고 이해하는 사람이 많다.
extern 키워드는 다른 파일에 선언되어 있는 변수를 링크시켜 자신이 만들고자 하는 프로그램에 쓸 수 있는 것이라
생각하면 된다. extern 키워드는 컴파일러에게

"이러한 변수가 어딘가에 선언되어 있고 그거 쓸꺼니까 메모리 올리지 말고 일단 그냥 넘어가~"
라는 말을 하는 것이다.

extern로 선언된 변수는 Link시에 심볼테이블을 검색을 통해 다른 obj들로 부터 찾게 된다.

다시 정리 하자!
extern 키워드를 사용해서 변수를 명시했다고 그것이 변수 선언을 의미하는게 아니다. 즉 메모리를 잡지 않는다는 것이다. 그 변수에 대한메모리는 다른 파일?에서 잡혀 있을거고, 링크타임때 그 변수에 대한 메모리를 찾아 링크시키는 것이다.
2009. 4. 9. 17:30

SSDT, IDT 후킹과 ntoskrl.exe를 이용한 복구에 대한 고찰

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
2008. 11. 1. 06:39

[펌] 전기자동차 분석과 비판

전기자동차의 월전기료(만원정도)와 엔진자동차의 월연료비를 비교해서 엄청나게 저렴한 유지비용인것처럼 보이지만 사실은 그렇지 않습니다. 전기자동차의 배터리비용도 포함되어야 제대로된 비교가 가능합니다. 이제 이것에 대해서 설명해 보겠습니다.

1. 전기자동차(5kw급)에 사용되는 배터리 및 월유지비
(1) 납축전지:수명2년, 가격150만원
(2) 리튬폴리머:수명5년, 가격700만원
(3) 월유지비(배터리비용+월전기료)
- 납축전지차:6만원+1만원=7만원
- 리튬폴리머차:11만원+1만원=12만원
(4) 배터리는 운행횟수에 관계없이 수명이 되면 교체해야함

2. 위의 예는 요즘 뉴스에 많이나오는 전기자동차의 경우로서 5kw 입니다. 엔진자동차 경차의 경우 30kw정도로 환산됩니다. 그러므로 위의 전기자동차를 30kw로 제작할경우 월유지비는 6배가 늘어납니다. 그래서 월유지비는 납축전지차는 40만원, 리튬폴리머차는 70만원정도로 계산됩니다.

3. 배터리는 수십년동안 연구개발되어 왔고, 여러분야(노트북, 핸드폰, UPS, 태양광발전)에서 기술개발을 요구하고 있습니다. 전기자동차에서 요구하는 배터리개발도 그중의 하나일 뿐입니다. 전기자동차 때문에 배터리성능이 획기적으로 개선되기는 힘들어 보입니다.

전기자동차 뉴스기사에서 이러한 부분을 취급하는 경우를 보지 못했습니다. 막대한 투자와 대량생산을 하면 획기적인 연구개발성과가 나와서 문제점이 해결되고 관련산업이 크게 성장할 것이라는 논리는 문제가 많습니다. 돈을 벌어서 이익을 내야한다는 생각보다는 전기자동차만이 가진 특수성을 발전시키는 방향으로 재정립하는 것이 필요하겠습니다.


* 참 고 *

1. 배터리중에 철배터리라는 것이 있습니다. 수명은 몇십년(50년이상 이라는 말도 있음) 사용 가능합니다. 안정성도 뛰어납니다. 이러한 철배터리같은 차원의 배터리는 몇가지 있습니다. 그러나 문제는 가격(10배), 무게(3배), 부피(5배) 입니다. 그래서 철배터리 무게와 부피를 고려하면 엔진자동차 준중형 정도로 제작해야 하므로 배터리가격만 7000만원정도, 전체 차량가격은 1억정도 될것입니다.

2. 경제성, 무게, 부피가 문제되지 않는다면 태양광 전기자동차의 연료비는 환상적 입니다. 20년 정도 사용 가능하고, 맑은날 낮에는 모든 연료비가 공짜입니다. 문제는 맑은날 낮에만 사용 가능하고, 가격은 2억~3억정도, 무게와 부피는 일반적인 자동차의 범위를 초월합니다.

3. 만약 경제성, 무게, 부피에서 획기적으로 개선된 배터리가 실용화 된다면 전기자동차는 엔진자동차를 대체하게 될것입니다. 전기자동차의 배터리는 차량지붕에 설치된 태양광전지(크기는 차량지붕 정도)로 충전하게 될것입니다. 이러한 배터리가 개발 된다면 전기자동차의 나머지 부분은 기존의 기술로도 충분히 실용화가 가능합니다. 또한, 현재까지의 태양광발전 기술로도 배터리충전 시키기에는 충분하므로 이러한 배터리를 이용한 태양광발전은 전기자동차 뿐만아니라 다른 여러분야에서도 활용가치가 엄청나게 많습니다. 그러므로 전기자동차와 태양광발전 두가지 모두에게 가장 중요한 것은 배터리 성능개선 입니다. 성능이 개선된 배터리는 많은 분야에서 가히 혁명적인 변화를 유도할 것입니다.


출처 : 네이버 badainside님들....
2008. 10. 16. 21:36

가비지 컬렉션의 동작원리


닷넷의 가바지 컬렉터가 작동하는 원리를 알아보자~ 메모리 할당, 메모리 관리, 메모리 해제로 크게 나누어
볼 수 있으며 메모리 할당은 일반적인 Heap과 마찬가지로 다음 할당할 포인터 위치를 가지는 포인팅을 하고
새 객체가 생성되면 그 객체의 크기를 조사하여 managed heap의 공간이 충분한지를 검사하게 된다.
만일 충분한 공간이 있다면 연속적으로 메모리 할당이 이루어지고 이러한 연속적인 메모리 할당을 통해
객체들끼리의 따른 접근속도가 빠른 이점을 가질 수 있는 것이다.( 비슷한 시기에 생성된 객체들은 인접한
공간에 할당되기 때문에 접근속도가 용이하다. )
 
할당과정을 간력히 적어보면

프로세스 초기화 -> 주소 공간 예약 및 포인팅 -> 객체생성 -> 새 객체의 메모리 용량 계산 -> 힙메모리 여유 공간 조사 -> 예약된 메모리 영역에 객체 할당 -> 다음 객체 포인터 이동

으로 요약된다.

메모리 관리를 위해서 가비지 컬렉터는 3가지의 세대로 분리하여 관리한다. 즉 매번 가비지 컬렉션 대상을 위해
모든 managed heap영역을 다 검사하지 않는다는 것이다. 실제로 모든 영역을 때마다 계속 하게되면 프로세스
구동에 있어서도 성능의 저하가 눈에 보이게 된다고 한다. 다시 돌아와서 CLR은 Heap영역을 0,1,2세대로 나누어서 관리한다고 했다. 객체가 제일처음 생성되면 0세대로 분류되고 다음 가비지컬렉션이 발생하여 쓰지 않는 메모리를 검사하는 과정에서 살아남은? 객체는 1세대로 올라가게 된다. 이렇게 하여 최대 2세대까지 올라갈 수 있게
되고 예로 main에서 쓰이는 객체경우 중간에 호출되는 메소드내의 객체보다는 오래 살 가능성이 크기 때문에
2세대까지 올라가는 경우가 많다고 생각하면 이해가 쉬울것이다.

결국 가비지 컬렉터는 할당하고자 하는 객체의 메모리 크기가 모자랄 경우 0세대를 검사하여 가비지를 골라내고
만일 이러한 한번의 과정을 통해서도 메모리의 부족할 경우 1세대에 대한 가비지 대상을 검사하게 된다. 이때
1세대를 검사할때는 그 밑의 세대인 0세대도 같이 수행하는데 이를 보면 결국 2세대까지 올라가서 검사를 한다는
것은 모든 managed heap영역을 검사한다는 말이 된다. 실제로 2세대까지 올라가서 검사하는 경우는 거의 없다고 한다.

0세대 가비지 수집 -> 메모리 부족 -> 1세대 가비지 수집(0세대 동반) -> 메모리 부족
-> 2세대 가비지 수집(1,0세대 동반)

그러면 가비지 수집은 어떻게 하는 것일까? 참조 경로에 대한 정보를 수집하는 것이다. 참조경로는 그럼 누가
될까? 참조경로는 첫번째 시작점으로 전역 객체나 정적 객체에 대한 참조가 루트가 된다. 또한 스택에 있는
지역변수, 매개변수의 객체 참조등도 루트가 될 수 있다. 이러한 참조를 이용하면 참조계수를 이용한 방법보다
안정적으로 사용할 수 있고 이렇게 참조정보를 수집한 그래프를 통해 참조 당하지 않는 객체를 가비지로 판단하는
것이다.

루트를 통해 참조 그래프를 생성하고 여기에 나타나는 않는 객체를 가비지가 된다. 이 객체에 대해서는 메모리 해제가 일어난다. 가비지 대상으로 표시된 영역에 대해 유효한 객체를 차례대로 재배치함으로써 덮어버리면서 연속적인 메모리 구조를 유지한다. 85KB이상의 큰 객체는 LOH( Large Object Heap )이라는 곳에 할당되고 이 영역은 재배치 하지 않는다. 너무 크기가 크기 때문에 재배치 자체가 메모리의 비효율을 가지고 오기 때문이다. 그 다음 살아남은 세대는 다음 세대로 올라가게 되고 최대 2세대까지 올라갈 수 있다고 했다. 가비지 컬렉션이 완료되면
다음 새 객체의 할당을 위해 빈 메모리의 시작주소를 새로 지정해 주게 됨으로써 모든 작업이 끝난다.

가비지 컬렉션 수행절차를 간략히 보자~

객체 그리프 생성 및 유효한 객체 추적 -> 가비지 객체 결정, 표시 -> 메모리 재배치( Memory Compaction ) -> 객체참조 값 조정 -> 유효 객체에 대한 세대 상승 -> 새로운 포인팅 

ps. '사랑하지 않으면 떠나라'인가..라는 책을 보면 저자가 인도의 개발자들을 뽑을 때 면접질문이 C#코딩으로 가비지 켈렉션을 뻗게 하는 방법이 어떤 것이 일을까? 라는 질문을 많이 했었다고 한다. 그때 제대로 틀린말조차
하는 사람이 없었다고 한다. 이러한 내부에 대한 이해가 없이 프로그램을 개발하는 경우가 많은 이때 여러 생각을 하게 했던 대목이였다.ㅎㅎ 이때쯤 한번씩 생각해보기 바란다. " C#코딩으로 가비지 켈렉션을 뻗게 하는 방법이 어떤 것이 일을까?"

참조 : 마소2008.04
2008. 10. 16. 19:58

가비지 컬렉션의 개념

닷넷환경에서 개발할 때 가장 큰 강점중에 하나가 가비지 컬렉션덕분에 메모리를 관리하지 않아도 된다는
점이다. C/C++기반의 프로그램을 개발하면 메모리 누수, 현수 포인터( 사용중인 객체가 해체되는 문제 ), 객체 손상등의 문제가 생길 수 있으며 이러한 위험적 요소를 직접 개발자에게 맡기지 않고 시스템에게 맡기는 것이
핵심이라고 할 수 있다.

닷넷의 공통 실행환경인 CLR( Common Language Runtime )은 가비지 컬렉터라는 일종의 백그라운드
서비스를 동작시켜 불필요해진 메모리 공간을 추적하고 여유공간을 확보해준다.

프로그램이 실행되기 위해서는 메모리에 관련된 데이터들이 올려져야하는 것은 당연한 이야기이다. 메모리를 보면
Code영역에 명령어
Data영역에 전역변수,static변수
Stack영역에 지역변수, 함수의 매개변수
Heap영역에 개발자에 의해 할당된 메모리영역

이라고 할 수 있다. 여기서 닷넷 응용프로그램은 CLR에 의해 직접 관리하는 Heap( managed heap )이 추가된다.
이렇게 되면 관리되는 Heap( managed heap )과 관리되지 않는 Heap( unmanaged heap )으로 나누어지게 되고
관리되지 않는 Heap에는 C/C++환경에서 동적으로 할당된 영역과 Win32 API, COM객체등이 대부분 이영역에
할당된다.

정리하자면 관리되는 Heap이란 닷넷 실행환경에서의 객체가 할당되는 메모리 공간으로 CLR에 의해 직접 관리되는 메모리 영역을 뜻한다.

참조요약 : 마소2008.04
2008. 10. 9. 19:37

Selinux 컴파일 서버

시그윈과의 라이브러리 충돌로 인해 Linux서버를 구축하고 거기에서 정책컴파일을 수행 후 컴파일정보와
컴파일한 정책결과파일을 다시 서버로 넘겨주는 방법으로 구현하였습니다.

컴파일중에 생길수 있는 에러메시지를 정책관리서버가 알수 있기 위해서는 log파일 작성이 필요했습니다.( log.txt )

한글이 깨졌네요..ㅡㅡ;
그냥 편하게 putty로 작업합시다..ㅎ


허브를 두었고 컴파일서버의 현재 IP주소는 192.168.0.47 입니다. 정책관리서버의 IP주소는 위에처럼 49로
주었습니다.


정책관리서버의 IP주소와 컴파일서버의 IP주소를 설정해주고~~


정책서버에서 컴파일버튼을 누르면 컴파일서버에서는 작업할 파일을 받아 이러한 파일의 전송을 보여주는 정보가 보이고 정책을 컴파일한 후 다시 정책서버로 넘겨줍니다.
정책서버에서는 컴파일서버로 부터 받은 로그정보를 뿌려주어 윈도우에서도 리눅스상의 컴파일정보를 볼 수 있게 됩니다.

                          < 컴파일서버에게 넘겨줄 전체 정책파일을 압축한 policy.zip파일 >



  < 컴파일서버로부터 받은 링크정보에 대한 file_contexts파일과 정책이미지 policy.19, 컴파일로그인 log.txt >

 


                                                                 < 로그정보 >

2008. 10. 9. 16:37

구글어스에 드디어 제가 찍은 사진이 떳습니다.ㅎㅎ


여러장 많이 등록했는데 한장만 제대로 등록되었네요..^^

사량도입구에서 찍었던 사진인데...

지구반대편에 사는 사람이 이 사진을 볼 수 있다는 생각에 뭔가 모를 짜릿함이..ㅡㅡㅎㅎ