블로그 이미지
.
속눈썹맨

공지사항

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

C++ reference와 pointer의 주소 차이

2005. 5. 25. 18:01 | Posted by 속눈썹맨
$ cat ./ref.cpp
#include <iostream>

using namespace std;

int main()
{
    int a = 10;
    int& b = a;
    int* c = &a;

    cout << "a : " << a << endl;
    cout << "&a : " << &a << endl;
    cout << "b : " << b << endl;
    cout << "&b : " << &b << endl;
    cout << "c : " << c << endl;
    cout << "&c : " << &c << endl;
    cout << "*c : " << *c << endl;

    return 0;
}
[ilashman@ob cpp_test]$ ./ref
a : 10
&a : 0xbfffecc4
b : 10
&b : 0xbfffecc4
c : 0xbfffecc4
&c : 0xbfffecbc
*c : 10

--------------------------------------
pointer는 indirect로 주소를 가리키는 것이지만
reference는 같은 주소를 가리키는 것이다.
따라서 변수 a와 변수 b는 주소가 0xbfffecc4로 같다.

C++ 상속과 생성자, 소멸자 호출

2005. 5. 25. 13:49 | Posted by 속눈썹맨
Base -> Derived로 상속했을 때.

Derived class를 만들면
생성자는 항상 Base(), Derived() 순으로 호출된다.

Derived class를 Derived pointer에 넣고 delete하면
소멸자는 ~Derived()가 호출되고 ~Base()가 호출된다.

Derived class를 Base pointer에 넣고 delete하면
소멸자는 ~Derived()가 호출되고 ~Base()가 virtual이면 호출되고 virtual이 아니면 Undefined이다.

@ class를 상속할 생각이라면 소멸자는 virtual로 만들자.

참고)
Effective C++, Item 14:  Make sure base classes have virtual destructors.

STL custom allocator

2005. 5. 24. 13:11 | Posted by 속눈썹맨
STL에 기본 할당자 대신 자신이 만든 것 이용하기
Effective STL ch.10, 11

예)
// SharedMemory Allocator
#include <map>
#include <string>
#include <vector>
#include <sys/types.h>
#include <sys/wait.h>
#include "mm.h"

void *mallocShared(size_t bytes)
{
    return MM_malloc(bytes);
}

void freeShared(void *p)
{
    MM_free(p);
}

template<typename T>
class SharedMemoryAllocator
{
    public:
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;
        typedef T* pointer;
        typedef const T * const_pointer;
        typedef T& reference;
        typedef const T * const_reference;
        typedef T value_type;

        template<typename U>
        struct rebind
        {
            typedef SharedMemoryAllocator<U> other;
        };

        SharedMemoryAllocator() throw() { }
        SharedMemoryAllocator(const SharedMemoryAllocator&) throw() { }

        template<typename U>
            SharedMemoryAllocator(const SharedMemoryAllocator<U>&) throw() { }

        ~SharedMemoryAllocator() throw() { }

        pointer address(reference __x) const { return &__x; }
        const_pointer address(const_reference __x) const { return &__x; }

        pointer allocate(size_type numObjects, const void *localityHint = 0)
        {
            return static_cast<pointer>(mallocShared(numObjects * sizeof(T)));
        }

        void deallocate(pointer ptrToMemory, size_type numObjects)
        {
            freeShared(ptrToMemory);
        }

        size_type max_size() const throw()
        {
            return size_t(-1) / sizeof(T);
        }

        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 402. wrong new expression in [some_] allocator::construct
        void construct(pointer __p, const T& __val)
        {
            new(__p) T(__val);  // placement new
        }

        void destroy(pointer __p)
        {
            __p->~T();
        }
};

template<typename T>
inline bool operator==(const SharedMemoryAllocator<T>&, const SharedMemoryAllocator<T>&)
{
    return true; // 왜 항상 true일까?
}

template<typename T>
inline bool operator!=(const SharedMemoryAllocator<T>&, const SharedMemoryAllocator<T>&)
{
    return false; // 왜 항상 false일까?
}

//! createOnShared로 만든 type은 꼭 destructor를 명시적으로 불러주어야 한다.
template<typename T>
T *createOnShared()
{
    void *chunk_p = mallocShared(sizeof(T)); // memory chunk
    if (chunk_p == NULL)
        return NULL;
    T *shm_p = new(chunk_p) T; // placement new(new가 실제로 메모리를 잡지는 않은)
    return shm_p;
}

template<typename T>
void releaseOnShared(T *shm_p)
{
    shm_p->~T();
    void *chunk_p = reinterpret_cast<void*>(shm_p);
    freeShared(chunk_p);
}

이용)
typedef std::vector<int, SharedMemoryAllocator<int> > SharedIntVector;
MM_create(100000000, "testtest");
SharedIntVector *plv = createOnShared<SharedIntVector>();
plv->push_back(1);
printf("MM_available : %d\n", MM_available());
releaseOnShared<SharedIntVector>(plv);

이용2)
// 참고
// /usr/include/c++/3.2.2/string
// /usr/include/c++/3.2.2/bits/stringfwd.h
    typedef std::basic_string<char, std::char_traits<char>, SharedMemoryAllocator<char> > SharedStr;

    typedef std::vector<SharedStr, SharedMemoryAllocator<SharedStr> > SharedStrVec;
// /usr/include/c++/3.2.2/map
// /usr/include/c++/3.2.2/bits/stl_map.h
    typedef std::map<SharedStr, SharedStr, less<SharedStr>, SharedMemoryAllocator<SharedStr> > SharedStrMap;

    void *pChunk1;
    pChunk1 = shAlloc1.malloc(sizeof(SharedStrVec));
    SharedStrVec *shVecStr1 = new(pChunk1) SharedStrVec;

    void *pChunk2;
    pChunk2 = shAlloc1.malloc(sizeof(SharedStrMap));
    SharedStrMap *map = new(pChunk2) SharedStrMap;
    shVecStr1->push_back("1");
    shVecStr1->push_back("2");
    shVecStr1->push_back("3");
    map->insert(SharedStrMap::value_type("1", "1"));
    map->insert(SharedStrMap::value_type("2", "2"));
    map->insert(SharedStrMap::value_type("3", "3"));

    pid_t p = fork();

    if (p == 0) {
        // child
        printf("child start\n");
        shVecStr1->push_back("4");
        shVecStr1->push_back("5");
        shVecStr1->push_back("6");
        map->insert(SharedStrMap::value_type("4", "4"));
        map->insert(SharedStrMap::value_type("5", "5"));
        map->insert(SharedStrMap::value_type("6", "6"));
        printf("child end\n");
        exit(0);
    } else if (p > 0) {
        // parent
        sleep(3);
        waitpid(p, NULL, 0);
        printf("parent start\n");
        shVecStr1->push_back("7");
        shVecStr1->push_back("8");
        shVecStr1->push_back("9");
        map->insert(SharedStrMap::value_type("7", "7"));
        map->insert(SharedStrMap::value_type("8", "8"));
        map->insert(SharedStrMap::value_type("9", "9"));

        SharedStrVec::iterator it;
        for (it = shVecStr1->begin(); it != shVecStr1->end(); it++) {
            printf("%s\n", it->c_str());
        }

        SharedStrMap::iterator it2;
        for (it2 = map->begin(); it2 != map->end(); it2++) {
            printf("%s -> %s \n", it2->first.c_str(), it2->second.c_str());
        }

        printf("parent end\n");
    } else {
        // error
        fprintf(stderr, "fork() failed.\n");
    }

    shVecStr1->~SharedStrVec();
    shAlloc1.free(pChunk1);
    map->~SharedStrMap();
    shAlloc1.free(pChunk2);

    return 0;
}

placement new

이미 메모리가 할당되어 있을 때,
그 메모리에 object를 넣고 생성자를 불러줌.
(일반적인 new와는 달리 메모리를 할당하는 일은 하지 않는 다.)

소멸자도 수동으로 불러줘야 하고
메모리 해제도 raw memory에 대해서 해줘야 한다.

참고)
More Effective C++, Item 4, 8
Linux에서 gcc 3.4를 설치한 후 /usr/include/c++/3.4/ext/new_allocator.h

Unix ps명령에서 ID대신 UID가 뜨는 이유

2005. 5. 20. 16:19 | Posted by 속눈썹맨
ID가 9글자 이상이면 ps에서 ID 대신 UID를 보여준다.

소스 : http://procps.sourceforge.net/
FreeBSD에서 ps 소스 보기 : /usr/src/bin/ps/

이유 설명
http://procps.sourceforge.net/faq.html
Why do long usernames get printed as numbers?

The UNIX and POSIX standards require that user names and group names be printed as decimal integers when there is not enough room in the column. Truncating the names, besides being a violation of the standard, would lead to confusion between names like MichelleRichards and MichelleRichardson. The UNIX and POSIX way to change column width is to rename the column:

     ps -o pid,user=CumbersomeUserNames -o comm
The easy way is to directly specify the desired width:
     ps -o pid,user:19,comm

유스호스텔증 만들기

2005. 5. 20. 15:00 | Posted by 속눈썹맨
가입비 : 1년 - 18,000원 (수수료등 포함하여 20,600원)

가입
http://www.kyha.or.kr/
site 가입 후 정회원 신청을 하면 가입 메일이 오고 2~3일 뒤에 카드도 옴.

예약(Booking)
http://www.hihostels.com/
신용카드를 이용

접수시각 : 24시간가능
Check-in 시각 : 15:00~22:00
아침에 도착하는 경우 :
07:00~10:00시에 체크인, 숙박신청, 짐을 맡김.

식사 : 대부분 가능, 취사가 가능할 수도 있음
       계절에 따라 쉬기도 하니 문의.

Perl로 구현한 SOAP Client

2005. 5. 19. 00:33 | Posted by 속눈썹맨
Perl로 구현한 SOAP Client
http://search.cpan.org/~pmqs/Compress-Zlib-1.34/Zlib.pm
http://search.cpan.org/~gaas/libwww-perl-5.803/lib/LWP.pm
-> Download: libwww-perl-5.803.tar.gz

perl Makefile.PL LIB=/home/ilashman/perl
make
make test
make install

export PERL5LIB=$PERL5LIB:/home/ilashman/perl

Google API SOAP이용하기

http://users.skynet.be/pascalbotte/rcx-ws-doc/perlpost.htm
이 프로그램을 그대로 쓰고 message와 POST만 바꾸면 된다.
http://www.google.com/apis/ 을 받아서
googleapi\soap-samples\doGoogleSearch.xml 의 내용을 message에 적는 다.
POST 이후의 url 주소는 'http://api.google.com/search/beta2'로 한다.

참고)
Google Hacks, OReilly, Chapter 5. Introducing the Google Web API
-> Hack 50 Programming the Google Web API with Perl

Python

2005. 5. 19. 00:33 | Posted by 속눈썹맨
Python
http://www.python.org/download/
-> Python 2.4.1 Windows installer

Active python
http://www.activestate.com/

wxPython
http://www.wxpython.org/
-> Download -> Binaries
-> wxPython2.6-win32-unicode-2.6.0.0-py24.exe
   wxPython2.6-win32-docs-demos-2.6.0.0.exe
  
http://wiki.wxpython.org/index.cgi/How_20to_20Learn_20wxPython
http://wiki.wxpython.org/
http://wiki.wxpython.org/index.cgi/Getting_20Started

Python Library Reference
http://www.python.org/doc/2.4.1/lib/lib.html

HTTP request보내기
http://www.python.org/doc/2.4.1/lib/module-httplib.html
http://www.python.org/doc/2.4.1/lib/httplib-examples.html

fpconst (A Python module for handling IEEE 754 floating point special values)
설치하기
http://research.warnes.net/projects/RStatServer/fpconst/
-> fpconst-0.7.2.zip
압축해제
cmd창 열기
c:\Python24\python.exe setup.py install

SOAPpy 설치하기
http://pywebsvcs.sourceforge.net/
SOAPpy-0.12.0.zip을 받음.
압축해제
cmd창 열기
c:\Python24\python.exe setup.py build
c:\Python24\python.exe setup.py install


파이썬 시작하기

---------------------------------
Python 예제 프로그램(Google API 이용하기)

import httplib, urllib

from wxPython.wx import *
class Form1(wxPanel):
    def __init__(self, parent, id):
        wxPanel.__init__(self, parent, id, wxPoint(), wxSize(500, 500))
        self.msgKeyword = wxStaticText(self, -1, "Keyword :", wxPoint(20, 30))
        self.keyword = wxTextCtrl(self, 20, "", wxPoint(100, 30), wxSize(140,-1))
        self.button = wxButton(self, 10, "Search", wxPoint(250, 30))
        EVT_BUTTON(self, 10, self.OnClick)
        self.display = wxTextCtrl(self, 5, "", wxPoint(20, 60), wxSize(700, 500),
                wxTE_MULTILINE | wxTE_READONLY)

    def OnClick(self,event):
        self.display.AppendText("Keyword: %s\n" % self.keyword.GetValue())
        headers = {"Content-type": "text/xml; charset=utf-8"}
        conn = httplib.HTTPConnection("api.google.com:80")
        conn.request("POST", "/search/beta2", "<?xml version='1.0' encoding='UTF-8'?> \
        <SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"> \
        <SOAP-ENV:Body> \
        <ns1:doGoogleSearch xmlns:ns1=\"urn:GoogleSearch\"  \
        SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"> \
        <key xsi:type=\"xsd:string\">키값</key> \
        <q xsi:type=\"xsd:string\">" + self.keyword.GetValue() "</q> \
        <start xsi:type=\"xsd:int\">0</start> \
        <maxResults xsi:type=\"xsd:int\">10</maxResults> \
        <filter xsi:type=\"xsd:boolean\">true</filter> \
        <restrict xsi:type=\"xsd:string\"></restrict> \
        <safeSearch xsi:type=\"xsd:boolean\">false</safeSearch> \
        <lr xsi:type=\"xsd:string\"></lr> \
        <ie xsi:type=\"xsd:string\">latin1</ie> \
        <oe xsi:type=\"xsd:string\">latin1</oe> \
        </ns1:doGoogleSearch> \
        </SOAP-ENV:Body> \
        </SOAP-ENV:Envelope>", headers)
        response = conn.getresponse()
        self.display.AppendText("%s\n" % response.status);
        self.display.AppendText("%s\n" % response.reason);
        data = response.read()
        conn.close()
        print data;
        self.display.AppendText( "%s\n" % data.decode('utf-8').encode('cp949') );

app = wxPySimpleApp()
frame = wxFrame(None, -1, " Our first Control")
Form1(frame, -1)
frame.Show(1)
app.MainLoop()

시스템 설계, 디자인, framework

2005. 5. 18. 16:37 | Posted by 속눈썹맨
Three-Tier(3tier) : Client-server model을 이용
http://en.wikipedia.org/wiki/3_tier
. User Interface
. Functional Business Logic
. Data storage

MVC(Model-view-controller)
http://en.wikipedia.org/wiki/Model-view-controller
. Data Model
. User Interface
. Control Logic

Middleware
http://en.wikipedia.org/wiki/Middleware

Stub = skeleton
http://www.webopedia.com/TERM/s/stub.html
RMI에서는 client side는 skeleton, Server side는 stub로 부른다.

Code Generator

IDL Compiler

RPC : Remote Procedure Call
RMI : Remote Method Invocation (JDK 1.1에서부터 지원)
DDE : Dynamic Data Exchange
OLE : Object Linking and Embedding
CORBA : Common Object Request Broker Architecture
COM : Component Object Model
EJB : Enterprise JavaBeans
J2EE : Java 2 Platform, Enterprise Edition

KAIST 학생 정보를 얻는 곳

2005. 5. 18. 12:30 | Posted by 속눈썹맨
. 교내 신문
. http://www.kaist.ac.kr
. http://portal.kaist.ac.kr/ -> 로그인 -> 공지사항
. 학사력
https://portal.kaist.ac.kr/webcais/devsso/history/history_calendar.php?affair_kind=1  
. BBS
  . ara
  . 친구들 보드 - loco, ska, bar, ara
. 과 홈페이지
  http://cs.kaist.ac.kr/

디지털 도어 락 해제법(Digital Door lock)

2005. 5. 18. 11:24 | Posted by 속눈썹맨
증상 : 버튼이 안 눌러짐(눌러도 효과음이 없고 반응이 없음)
       문이 안 열림.
       경고벨이 쉬지 않고 울림.

제품명 : Gateman art
원인 : 배터리가 다 되서 시스템이 나가버렸음.

준비물 : 9V 건전지(양 극이 같은 방향에 있는 것) 1개,
         1.5V AAA 건전지 4개,
         알루미늄 호일(or 전선)
         -> 총 가격 : 1만원
해결책 :
. 9V 건전지를 디지털 도어락 옆구리의 쇠부분에 한 전극당 하나씩 갖다 댄다.
  (Position이 안 맞아서 전지만 가지고는 정확하게
   접촉이 안되어 전기가 흐르지 않으므로 전선이나
   알루미늄 호일로 잘 연결한다.)
. 경고벨이 꺼지고 조용해 진다.
. 계속 대고 있는 상태에서 비밀번호를 눌러 문을 연다.
. 1.5V AAA 건전지 4개를 교체한다.
소요시간 : 준비물 구입, 고민, A/S 전화시간, 기타 삽질시간 합쳐서 30분

참고)
. 알루미늄 호일로 전극을 연장할 때 실수로 두 전극이 닿게하지 않도록 주의한다.
  불꽃이 튀면서 방전(단락, short)되어 버린다.
. 열쇠집가도 A/S 센터로 연락하라고만 한다. 결국 자신이 해결해야 한다.
. 집이 동네 슈퍼에서 멀다면 이런 락은 안 좋다. -.-

전조증상)
. 평소부터 버튼이 잘 안 눌리고 문이 안 열리면 언제든 이런 일이 생길 수 있다.
. 안쪽에서 버튼이 안열려서 돌려서 연다든지, 바깥쪽에서 버튼을 누르는 데 실패한다든지 하는 것들.

문의전화 : 디지털락 하단에 적혀 있다.
           (종류에 따라 상단, 측면, 앞면에 적혀있을 수도 있다.)
           ARS : 080-700-0789 상담원 : 2->2