2012.02.20 07:45

[작성중] 알려진 포트

Lyn
조회 수 24618 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

TCP


21 : Ftp

22 : SSH

80 : Http

443 : Https

3389 : RDP (Windows 원격 데스크탑)


?

Lyn
조회 수 32209 추천 수 0 댓글 4
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++의 STL 에서는 여러가지 알고리즘을 제공한다.
그중 "임의의" 동작을 할 수 있는 알고리즘들은 그 "동작" 의 대상이 되는 인자를 받도록 되어 있는데, 
그 "동작"의 조건은 ()연산자로 호출이 가능할것! 이다.


그 동작을 만족시키는것은 C에서는 함수가 있다.
또 C++에서는 STL 과 함께 소개된 함수객체(Functor)가 있으며, STL 초기부터 제공된 bind1st, bind2nd가 있고, boost에서 제공되는 mem_fn 도 있으며, 이 모든것을 통합한 범용 bind(C++11 or boost에 포함)도 존재한다.

그리고 최신의 C++11 표준에 포함된 lambda도 있고, boost의 lambda도 있지만, 이쪽은 C++11 표준에 lambda가 포함 된 이상 더이상 쓸 일은 없을테니 이번 실험에선 제외한다.


실험순서는 전역함수, bind된 전역함수, 함수객체, 람다, bind된 람다, auto를 이용해 bind된 람다 의 순이다.

실험은 Visual C++ 2010 Sp1, x86 Debug Build에서 테스트 하엿다. Release Mode 도 특성은 동일하다.

궂이 Debug Build로 테스트 한 이유는 Release모드에서 자꾸 전역함수를 inline화 시키는 바람에 =_=;


코드 나간다.


#include <cstdlib>
#include <cstdio>
#include <vector>
#include <random>
#include <cstdint>
#include <algorithm>
#include <functional>
#include <windows.h>
 
using namespace std;
 
__int64 g_NumberSum;
 
void GetSumFunction(int Num)
{
	g_NumberSum = g_NumberSum + Num;
}
 
struct GetSumFunctor
{
	void operator()(int Num)
	{
		g_NumberSum = g_NumberSum + Num;
	}
};
 
void wmain()
{
	const int NUMBER_COUNT = 100000000;
 
	mt19937_64 RandomEngine;
	uniform_int <> RandomRange(0, INT32_MAX);
	RandomEngine.seed(GetTickCount());
 
	vector<int> RandumNumbers;
	RandumNumbers.reserve(NUMBER_COUNT);
	for (int i = 0; i < NUMBER_COUNT; ++i)
	{
		RandumNumbers.push_back(RandomRange(RandomEngine));
	}
 
	DWORD Tick;
//function
	g_NumberSum = 0;
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), GetSumFunction);
	printf("Global Function :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//bind function
	g_NumberSum = 0;
	function<void(int)> FunctionObject = bind(&GetSumFunction, tr1::placeholders::_1);
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), FunctionObject);
	printf("Bind Function   :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//functor
	g_NumberSum = 0;
	Tick = GetTickCount();	
	for_each(RandumNumbers.begin(), RandumNumbers.end(), GetSumFunctor());
	printf("Functor         :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++ 11 Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	for_each(RandumNumbers.begin(), RandumNumbers.end(), 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		});
	printf("C++11 Lambda    :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++11 Bind Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	function<void(int)> BindLambda = 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		};
	for_each(RandumNumbers.begin(), RandumNumbers.end(), BindLambda);
	printf("Bind Lambda     :: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick);
//C++11 Auto bind Lambda
	g_NumberSum = 0;
	Tick = GetTickCount();
	auto AutoBindLambda = 
		[](int Num)
		{
			g_NumberSum = g_NumberSum + Num;
		};
	for_each(RandumNumbers.begin(), RandumNumbers.end(), AutoBindLambda);
	printf("Auto Bind Lambda:: Sum : %I64d, Time : %dms\n", g_NumberSum, GetTickCount() - Tick); 
} 



아래는 결과이다.

lambda.png


결과를 보면 lambda 가 가장 빠른 것을 볼 수 있다. 길게 나불대지 않고 성능 이슈와 원인을 아래 간략히 적어본다.
1. 전역함수의 경우 함수 Call 오버헤드에 의해 속도가 조금 감소하엿다.

2. lambda, functor 는 사실상 오차범위 내의 차이라고 보인다.

3. bind lambda 의 경우는 std::fuction 객체가 함수호출 정보를 RTTI에 의존하는 특징때문에 속도를 왕창 까먹게 된다.

4. bind 된 전역함수의 경우는 RTTI의 오버헤드 + 함수호출로 인해 가장 느려진다.

5. auto를 사용해 변수에 저장한 lambda 는 std::fuction객체에 저장 하는 것이 아니라 일종의 inline 함수처럼 구현해준다. 그래서 오버헤드가 전혀 없이 빠른 속도를 보여준다. 즉 같은 함수객체를 2번이상 이용 할 경우 코드를 Copy&Paste 하지 않아도 auto를 이용하면 성능과 중복방지 두마리 코드를 다 잡을 수 있다.

?
  • ?
    elrha 2012.08.16 18:27

    으아 이거 좋은정보네요


    테스트는 안해봤지만 auto 객체 마우스 오버해보면 std::function으로 나올듯 한데..


    결국 컴파일러 지능테스트인건가요 ㅋㅋㅋㅋ

  • profile
    Lyn 2012.08.17 07:23

    아뇨 함수포인터 취급해요 ㅎㅎ


    컴파일 타임에 완전한 호출 정보를 알고있는 상황에서 궂이 오버헤드가 있는 std::function으로 컴파일할 이유가 없죠

  • ?
    11ho 2014.03.25 05:22
    감사합니다. 속이 다 후련하네요 ㅠㅠ
  • ?
    해피 2015.07.17 18:45
    퍼가용

2012.01.14 00:40

Boost 빌드 방법

Lyn
조회 수 31501 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
1. Gem 만들기
bootstrap 실행 -> b2 실행파일이 생성

1.48.0에선 bjam -> b2 로 바뀌었다. 근데 bjam 도 그대로 된다 (...) 같은걸 2개 만들어줌

2. b2 빌드옵션
toolset=<>            ▷ 컴파일러 설정
--buildtype=<>      ▷ 빌드방법 설정
--libdir=<>            ▷ output 폴더 설정
--architecture=<>   ▷ target platform 설정
address-model=<>  ▷ bit수 설정
install                    ▷ 빌드방법 설정
define=<>              ▷ define 상수 설정
-j<>                      ▷ 병렬컴파일할 코어갯수 설정

절대로 = 앞뒤에 공백 넣지 말것. 반드시 원하는 컴파일러/bit수의 Command Prompt  에서 실행할것

3. 예제
vc++ 2010으로 모든형태의 라이브러리(debug dll, debug static, release dll, release static)를 CRT 버전을 최신으로 하여 특정 Path에  쿼드코어로 빌드 할경우

AMD64(EM64T)는 x86 아키텍쳐에 address 를 64bit로 지정해야한다. x64, AMD64, EM64T 등의 키워드는 불가능

  1. 32bit build

    b2 -j4 toolset=msvc-10.0 --build-type=complete define=_BIND_TO_CURRENT_VCLIBS_VERSION  --libdir=c:\library\boost\lib\i386 install

  2. 64bit build
    b2 -j4 toolset=msvc-10.0 --build-type=complete  define=_BIND_TO_CURRENT_VCLIBS_VERSION --libdir=c:\library\boost\lib\amd64 architecture=x86 address-model=64 install
?
  • profile
    Lyn 2012.01.14 00:41

    실수로 글을 지워서 다시썻다 씁 ㅡㅡ;


Lyn
조회 수 25007 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

DLLMain은 WinMain 이나 main 과는 다르게 제약이 많다.

나도 이걸로 크래시 낸 적이 많이몇번 있고 ... 


DLLMain은 일종의 "객체의생성자" 라고 보면 비슷하다.

"로딩중" 인 것이지 로딩이 끝난것이 아니다 라는것이다.


아래에는 Attach 시 기준으로 적었지만, Detach 에도 별 다를건 없다. kerner32.dll 이외의 dll은 이미 언로딩 되어있을 수도 있다.


이제 하지 말아야할것을 슬~슬 나열 해 보자. 


1. kernel32.dll 이외의 dll에 있는 함수 대부분.

kernel32.dll 이외의 dll이 로딩되어 있다는 보장은 전혀없다


2. 동기화코드

락, 언락 등의 코드


3. LoadLibrary, CreateProcess

다른 DLL 쓰지말라는말과 일맥상통. 


4. 전역객체 초기화, 메모리할당 등

메모리메니저가 로딩되었다는 보장이 없다


5. COM관련 코드

역시 보장없다


6. 예외 throw

C++ 객체 생성자에서 throw 하는것과 비슷한 대략므흣한 (...) 상황이 발생한다.


결론. 

DLLMain은 걍 비워 둬라. 그리고 Initialize 함수를 제공해라.
상당수의 라이브러리가 라이브러리 초기화 함수를 제공하는것은 다 이유가 있다!

(당장 GDI+와 Winsock2를 생각해봐라!) 

?

2012.01.01 07:14

새해다 ...

Lyn
조회 수 28070 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

뭐 업다 18 ㅜㅜ

?

Lyn
조회 수 29722 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Trac, Mantis, Redmine 은 기본적으로 UTF-8을 사용한다.

그러나 VC++은 소스를 ascii로 저장하기 때문에 저장소 연동을 하면 소스에서 한글이 다 박살난 채로 보이게 된다.

이것을 해결하기위해서는 소스를 UTF-8로 저장 해야 되는데, 저장시 자동으로 UTF-8로 변환을 하는 매크로가 있다



MacroIDE -> EnviromentEvents에


Imports System.IO


추가 한다. 그 아래에


Sub MakeUTF8File(ByVal path As String)

    Dim input As New FileStream(path, FileMode.Open)


    'Check BOM

    Dim isUTF8 As Boolean = (input.ReadByte = &HEF And input.ReadByte = &HBB And input.ReadByte = &HBF)

    input.Close()


    If (Not isUTF8) Then

        Dim s As String

        s = File.ReadAllText(path, System.Text.Encoding.Default)

        File.WriteAllText(path, s, System.Text.Encoding.UTF8)

    End If

End Sub


Public Sub DocumentEvents_DocumentSaved(ByVal Document As EnvDTE.Document) Handles DocumentEvents.DocumentSaved

    Dim path As String = Document.FullName

    MakeUTF8File(path)

End Sub


를 추가한다.



PS. trac은 지금 안 쓰고있어 확인이 안되는데 redmine 은 그냥 소스 인코딩을 추가해주면 간단히 해결된다 (...) 걍 euc-kr 등록해두자



?

Lyn
조회 수 28087 추천 수 0 댓글 0
Atachment
첨부 '2'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

멀티미디어 타이머를 시작하기 위해 timeSetEvent 를 호출하면



1.png

2.png


결과적으로 timeBeginPeriod 가 호출된다.

멀티미디어 타이머 해상도의 비밀은 timeBeginPeriod 이었던것!

?

Lyn
조회 수 27873 추천 수 0 댓글 0
Atachment
첨부 '2'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

Cilk plus 자료와 Sample Code

?

Lyn
조회 수 28216 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
VS2010에서 코드를 치려고 하면 아래와 같은 팝업이 뜨면서 툴이 제대로 동작 하지 않는 경우가 있다.
(주로 빨간줄 잘못긋기, 인텔리센스 맛가기 등등 ...)

Visual Studio has encountered an exception.PNG

Visual Studio has encountered an exception. This may be caused by an extension. You can get more information by running the application together with the /log parameter on the command line, and then examining the file 'C:\Users\USERNAME\AppData\Roaming\Microsoft\VisualStudio\10.0\ActivityLog.xml'

이경우 레지스트리 수정으로 해결이 가능 한데, 

32Bit의 경우
[HKEY_CLASSES_ROOT\CLSID\{73B7DC00-F498-4ABD-AB79-D07AFD52F395}\InProcServer32]
의 Default 값을 
"C:\Program Files\Common Files\Microsoft Shared\MSEnv\TextMgrP.dll" 으로


64Bit의 경우
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{73B7DC00-F498-4ABD-AB79-D07AFD52F395}\InProcServer32]
의 Default 값을 
"C:\Program Files (x86)\Common Files\Microsoft Shared\MSEnv\TextMgrP.dll" 으로 수정한다.


만약 기본폴더가 아닌 다른 곳에 설치 했다면 적당히 값 조절해라.
?
  • ?
    챙고 2013.11.13 18:26
    안녕하세요, 25살 이제 막 opencv에 들어선 대학생입니다.
    이 오류때문에 3일동안 아무것도 진전이 안되더군요.
    이 방법을 사용해 보려고하는데 제가 초보중에 초보여서..
    default 값을 변경해주는 방법을 모르겠습니다 ㅠ
    혹시 그 부분을 조금만 더 알려주실수 있나요?
    답변 기다리겠습니다.

Lyn
조회 수 27421 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

C++ 코딩을 하다 보면 복사 되지 말아야 하는 객체가 참 많다...


특히 포인터를 소유하고 있는 객체들이 그런데, Copy Constructor 를 만들어 주면 간단한 일이지만...  일일히 하기도 난감하고 Mutex 객체 등은 Copy Constructor 조차 의미가 없고 레퍼런스 카운팅을 해야 되는 더러운 상황이 된다.


이럴땐 간단히 Copy Constructor 를 private에 선언해서 차단 할 수 있는데... 이걸 일일히 해주자니 또 귀찮은게 인지상정이라...


이런것을 간단히 해결해 주는 class가 있다


boost::noncopyable 인데


boost/utility.hpp 에 존재한다.


간단히 boost::noncopyable 를 private 상속(상속시 접근지정자를 쓰지 않으면 private 다!) 해주면 된다.

너무 간단 하므로 샘플따위 없다 (...) 딴데가서 알아봐라

?

2011.03.31 08:21

Mysql 툴

Lyn
조회 수 37433 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

2015년 7월 현재 상황이 많이 바뀌었다.

HeidiSQL 은 발전이 없고, Mysql Workbench 는 엄청 좋아졋다. 특히 DB가 클 경우 HeidiSQL 은 테이블 목록 불러오는데만도 세월을 느낄 수 있을 정도이다.

HeidiSQL 을 쓸 경우는 그저 MariaDB 10.x 를 사용할 때 뿐이다(MariaDB와 같이 배포되며, Workbench 는 MariaDB 10.x를 지원하지 않는다)

 

HeidiSQL

 

MysqlFront 이제 구버전이다

 

TAG •
?

Lyn
조회 수 37113 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

1. 자동업데이트(이거 이슈 거의 무조건 생기는거 같다..)


2. 서버인증


3. 패킷 암호화


4. 접속유지체크(이걸 프레임워크단에 넣어야하나 어플단에서 구현해야하나...)


5. 일부 알고리즘을 분리해서 인증없이 실행 안되도록.


6. 크래시 덤프



?

Lyn
조회 수 42331 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

XMarks : 북마크 동기화


Fire Gesutrs : 제스쳐


FasterFox : 속도 증가(캐시 이용)

?

Lyn
조회 수 39265 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Non-ASCII_Characters


번역중


헤더파일

  - 중복방지를 위한 헤더가드 : 모든 헤더는 중복 include 를 막기 위한 헤더가드를 가진다. 이는 <PROJECT>_<PATH>_<FILE>_H_ 의 포맷으로 만들어져있어야 한다

  - 헤더파일 의존성 : 번역중

  - 인라인 함수 : 10줄 혹은 그보다 작은 함수에만 사용한다.

  - -ini.h 파일 : 복잡한 인라인함수를 만들어야 할 때 ~ini.h 형태를 사용한다

  - 함수 파라메터 순서 : 함수 파라메터는 입력파라메터가 출력 파라메터보다 먼저 온다



?

Lyn
조회 수 37730 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

boost  shared_ptr 은 편한 놈이지만..

문제가 생기는 상황이 몇 가지 있다 있다그 중 하나 바로 객체 내부에서 전역 함수(혹은 다른 class 의 함수)를 호출 할 때 this 를 넘기는 문제인데

 

왜나면 아래와 같은 코드가 안되기 때문이다.

 

shared_ptr과 포인터형은 서로 대입이 되지 않기 때문에 위와 같은 코드는 컴파일 에러를 뱉는다그럼 아래와 같이 고치면 어떨까.

 

 

this 를 shared_ptr<SPtrTestthisptr(this);

로 변환 해서 넘겻다.

 

이렇게 하면.

SPtrTest::Operation이 끝날때와 Func 가 끝날 때 2 destructor 가 호출 되게 되어 에러가 난다.

이걸 방지하는 방법은 자기 자신의 shared_ptr 을 레퍼런스 카운트 문제가 생기지 않도록(this 를 넘길 때도 레퍼런스 카운터가 증가 하는하는 것이다.

 

즉 boost::enable_shared_from_this<T> 를 상속 받은 class 를 만드는 방법이다.

boost::enable_shared_from_this<T> 를 상속 받은 뒤 shared_from_this() 를 호출 하면 자기 자신의 shared_ptr 을 리턴 해 준다.

 

그럼 아래와 같이 된다

#include <boost/shared_ptr.hpp>

#include <cstdio>

 

using namespace boost;

 

class SPtrTest;

 

void Func(shared_ptr<SPtrTestsp);

 

class SPtrTest

{

public:

        int var1;

        SPtrTest()

        {

               printf("Constructor\n");

        }

        ~SPtrTest()

        {

               printf("Destructor\n");

        }

        void operation()

        {

              

               Func(this);

        }

};

 

void Func(shared_ptr<SPtrTestsp)

{

        sp->var1++;

        printf("%d\n"sp->var1);

};

 

int _tmain(int argc_TCHARargv[])

{

 

        shared_ptr<SPtrTesttestclass(new SPtrTest);

        testclass->var1 = 0;

        testclass->operation();

              

        return 0;

}

 

이렇게 하면 아무 문제 없이 작동이 가능하다.

 

 

 

Ps. 특히 조심해야 할 것은..

shared_ptr<SPtrTestthisptr(this); 를 여러 번 생성 한다고 레퍼런스 카운터가 증가하는 것은 아니다레퍼런스 카운터의 증가는 변수끼리의 대입에 의해서만 증가할 뿐저런 선언은 카운터1짜리 변수를 여러 개 늘려 에러를 내게 할 뿐이다.

#include <boost/shared_ptr.hpp>

#include <cstdio>

 

using namespace boost;

 

class SPtrTest;

 

void Func(shared_ptr<SPtrTestsp);

 

class SPtrTest

{

public:

        int var1;

        SPtrTest()

        {

               printf("Constructor\n");

        }

        ~SPtrTest()

        {

               printf("Destructor\n");

        }

        void operation()

        {

               shared_ptr<SPtrTestthisptr(this);

               Func(thisptr);

        }

};

 

void Func(shared_ptr<SPtrTestsp)

{

        sp->var1++;

        printf("%d\n"sp->var1);

};

 

int _tmain(int argc_TCHARargv[])

{

 

        shared_ptr<SPtrTesttestclass(new SPtrTest);

        testclass->var1 = 0;

        testclass->operation();

              

        return 0;

}




#include <boost/shared_ptr.hpp>

#include <boost/weak_ptr.hpp>

#include <boost/smart_ptr/enable_shared_from_this.hpp>

#include <cstdio>

 

using namespace boost;

 

class SPtrTest;

 

void Func(shared_ptr<SPtrTestsp);

 

class SPtrTest : public boost::enable_shared_from_this<SPtrTest>

{

public:

        int var1;

        SPtrTest()

        {

               printf("Constructor\n");

        }

        ~SPtrTest()

        {

               printf("Destructor\n");

        }

        void operation()

        {

               Func(shared_from_this());

        }

};

 

void Func(shared_ptr<SPtrTestsp)

{

        sp->var1++;

        printf("%d\n"sp->var1);

};

 

int _tmain(int argc_TCHARargv[])

{

 

        shared_ptr<SPtrTesttestclass(new SPtrTest);

        testclass->var1 = 0;

        testclass->operation();

              

        return 0;

}

?

Lyn
조회 수 34301 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

==여기서부턴 내 개인적인 생각이니... 할말있으면 태클 거는건 좋다.==

 

프로그래머에게 앱스토어의 유행이란 과연 무엇일까..

 

 

혹자는 이렇게 말할지도 모른다. 개인 개발자들에게 대박의 기회를 주었다고...

물론 난 대박이란 말을 좋아하지 않는다. 왠지 운으로 된 것이라는 느낌을 강하게 주기때문에. 하지만 여기선 딱히 쓸 말이 없는 거 같아 그냥 대박이라 표현하기로 하자. 내 짧은 어휘력에 저주를 한번 보내주는 것은 좋다.

 

이 얘기는 물론 대박을 친 사람이 있다는 얘기는 아니다.

난 아직까지 앱스토어에서 대박친 사람을 본 적이 없다. 기껏해야 중박정도랄까. 애시당초 큰 돈을 벌 수 있는 시스템이 아니다.

그리고 앱스토어는 이제 개인 한두명일 달라붙을 수 있는 시장이 아니라 규모를 갖춘 팀이 아니면 승부를 하기 힘든 시장이다.

 

 

내가 말하고싶은건 뭐냐...

프로그래머에게 앱스토어는 저주나 다름없다는 것이다. 적어도 한국에서는..

공짜 혹은 비싸봐야 천원내지 수천원 이건 무슨 의미냐. 프로그램은 "싸다" 라는 인식을 사람들에게 박아준 것 이외엔 아무것도 아니다.

프로그램은 엄청난 인건비를 소모 해야만 만들 수 있다. 그런것이 천원 이천원에 팔린다는것은 가치를 우리 스스로 무시한 것 외에 아무것도 아니다.

 

프로그래머들의 재미있는 장난감이 될 수는 있다 앱스토어가. 하지만 재미삼아 만들었으면 그것으로 끝내라. 그걸 싼값에 공개하는건 우리 스스로 가치를 깎아먹는 것 밖에는 안된다. 

 

중급개발자가 월급이 300만원이라고 하면 시간당 2만원을 버는셈인데... 그것을 1달러(대충 1000원으로 치자) 에 판다고 하자.

아이폰 앱스토어에서 100개 이상 팔리는 어플의 비율이 10% 정도라고 하는데... 상위 10%의 어플을 만들어 냇다고 치자. 그럼 10만원을 버는 셈이다. 당신이 그걸 5시간 이내에 완성한 것이 아니라면 완전한 손해라고 밖에 할 수 없다.

?

Lyn
조회 수 39615 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

볼포 모임에서도 이런저런 얘기 하다 나온거지만...

델파이 / C++빌더 초보들은 웃기는 특징을 하나 가지고 있다.



뭔가 하다가 안된다.

그럼 이렇게 생각한다. '아 이게 델파이의 한계인가'


.... 웃긴다.

그런사람들이 VC를 하면서 똑같은 문제에 부딛히면 이렇게 생각한다 '아 내가 뭘 잘못한게 있나보다'

... 진짜 웃긴다




뭔가 하려고 할때 개발툴 자체에 한계가 있는 경우는 드물다.

(물론 VM 의 한계, Native의 한계 등이 있지만... 이 경우는 애초에 언어선택자체가 잘못된거니까 제쳐두자.)

개발툴 탓하기 전에 자신의 실력을 한번쯤 돌아보길.





근데... 난 델파이 프로그래머 아니잖아.... 안될거야 아마

?

Lyn
조회 수 39048 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

1. Visual Studio 2008  2010 + Intel C++ 11.1 12.1 // 개발툴.

    - Visual Assist // VS Add-on


2. Delphi 2007, Delphi 2010 XE2 //개발툴

    -Castailla // Delphi Add-on


3. VirtualBox 

가상머신 가벼워서 자주 이용


3. VMWare

VirtualBox 가 불안해서 VMWare로 완전 이사


4. TeraCopy

쉘확장. 윈도우의 파일복사/이동 기능을 확장해줌.

복사중 일부분 취소, 일시정지, Copy<->Move 전환기능 등


걍 Total Commander 쓰기로 했다. 윈도7에선 TeraCopy가 너무 느리다.


5. Microsoft Office 200 2010 // 문서


6. Total Commander

다기능 툴이지만 파일이름변경, FTP 등의 기능을 주로 이용


7. 구글 크롬

    - IE Tab

    - Gesture

초고속 웹 브라우저


8. Beyond Compare 3

파일비교 솔루션. 개발보조툴


9. Tortoise SVN, TortoiseHG

SVN 프론트엔드. 개발보조툴


10. Warcraft III, Startcraft II

게임


11. NateOn, Google Talk, MSN

메신저

?

Lyn
조회 수 40815 추천 수 0 댓글 1
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

- 2010.1.3 지금 이걸 계속 써야 하나 말아야하나 고민중이다. 단돈 몇만원이 아까운게 아니라면 Beyond Compare 사서 써라. 진리다. 비교할 의미자체를 모르겠다(단. 3Way Marge 는 내가 쓰지 않아 잘 모른다)

  2011.11.22 2년사이에 많이 바뀌어서 내용을 추가


[파일비교]

Araxis Merge :

  달라진 부분을 보여주는 가이드라인이 너무 작아서 눈에 띄지 않음.

  단 선으로 바뀐 부분을 보여주기에 매우 많은 길이의 코드가 연속적으로 달라졋을 경우 직관적.

 

Beyond Compare :

  바뀐 부분을 영역색, 글씨색으로 나누어 보여주어서 보기 편함.

  달라진 부분을 보여주는 가이드라인의 길이가 화면크기와 별도로 나타나 직관적이지 않음.

  바뀐 부분이 한 줄의 일부, 아니면 몇줄 이하일 경우 직관적으로 보이나, 바뀐 부분의 길이가 길 경우, 특히 한페이지가 넘어 갈 경우는 보기가 상당히 불편하다.

 

Ultra Compare : 

  돈내고 쓸 가치가 없다. 알고리즘이 개판이다.


Kdiff

  한글 지원이 쓰레기 of 쓰레기라 배제


WinMerge

  제작자는 이 UI로 정말 코드 비교를 할수 있는지 한번 묻고싶다


[폴더비교]

Araxis Merge :

  폴더 비교 창이 매우 난잡하여 보기힘들다.

  필터가 매우 단순

  최신버전에서 필터 기능이 강력해졋다

Beyond Compare :

  알아보기 쉽게 색으로 잘 표시되어 있다.

  필터링 기능이 매우 막강하다. 특히 프로그래머가 jpg, bmp 파일을 Compare 툴로 보는것은 의미가 없는데 필터 옵션에서 아주 간단하게 걸러낼 수 있다.


[기타기능]

Araxis Merge:

  소스비교, 바이너리 비교. 그 이상의 잡기능은 없다

Beyond Compare:

  Mp3비교, 이미지 비교 등등 굉장히 다양한 포맷을 비교하는 기능을 제공한다.


[가격]

Araxis Merge :

  비싼 값에 비해, 밥값을 못한다.

  이제 밥값정돈 한다. 그래도 비싸다

Beyond Compare :

  유료이긴 하지만 비싸지 않고, 이 가격대에 이정도 툴이면 매우 훌륭하다.

 

KDiff, WinMerge : 

  싼게 비지떡이다. 정말 돈이 없다면 그때나 고민해 보자


 

PS. DiffMerge, AcroDiff 등 비교 예정

?

2009.08.19 03:08

C++ new 연산자의 진실

Lyn
조회 수 57826 추천 수 0 댓글 2
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

new 연산자의 진실

 

C++에서는 메모리를 할당할 때 new 연산자를 사용합니다.

그리고 이 new 라는 연산자는 오버로딩이 가능합니다. 그럼 과연 이 new 의 정체는 뭘까요?

new 를 호출하면 실제로는 malloc 이 내부에서 다시 호출 된 다는 것은 일단 다 안다고 가정하고 넘어가겠습니다.

 

첫 코드 나갑니다. 연산자 new 를 오버로딩 한 경우입니다.

#include <stdio.h>

#include <stdlib.h>

 

class Test

{

public:

           int a;

 

           void* operator new(size_t size)

           {

                     printf("한 개 할당중\n");

                     Test* temp = (Test*)malloc(size);

                     return temp;

           }

           Test()

           {

                     printf("Test Constructor\n");

           }

};

int main()

{

           Test* t1;

 

           t1 = new Test;

 

           system("pause");

           return 0;

}

 

new 에는 size_t 형태의 파라메터가 하나 존재합니다. 이 파라메터로 할당 해야 할 크기를 알려줍니다. 단순히 그 크기로 메모리를 할당 하고 리턴 만 하엿습니다.

 

실행결과는 아래와 같습니다.

 

image1.png

 

우리는 부른적도 없는 생성자가 호출되었습니다. new 가 단순히 메모리 할당만 하도록 오버로딩 하엿는데요. 여기서 new 는 실제로는 오버로딩이 되지 않았다고 할 수 있겠습니다. 뭔가 수상하군요. 디스어셈블 해 보았습니다.

 

image2.png

 

이런 우리는 new 를 호출했을 뿐인데 실제로는 operator new 라는 함수와 생성자를 따로따로 호출 하고 있었네요. 그럼 우리가 수정한 것은 operator new 라는 함수 일 뿐 new 연산자 자체가 아니라는것을 알 수 있습니다.

 

심지어 윗줄에서는 할당 할 메모리 크기를 스택에 집어넣어주는 친절함(?) 까지 엿볼 수 있군요. Pop 이 호출부위 아래에 존재한다는 것은 operator new cdecl 방식으로 call 되고 있다고 짐작 할 수 있겠습니다.

 

그럼 new 는 단지 operator new 와 생성자를 호출 하고 있을 뿐이라면 이 두 함수를 따로 따로 호출하는것도 가능하지 않을까요? 다음과 같은 코드를 짜 보았습니다.

#include <stdio.h>

#include <stdlib.h>

 

class Test

{

public:

           int a;

 

           void* operator new(size_t size)

           {

                     printf("한 개 할당중\n");

                     Test* temp = (Test*)malloc(size);

                     return temp;

           }

           Test()

           {

                     printf("Test Constructor\n");

           }

};

int main()

{

           Test* t1;

 

           t1 = (Test*)Test::operator new(sizeof(Test));

           t1:Test();

 

           system("pause");

           return 0;

}

 

그리고 실행 해 보았습니다.

 

image3.png

 

이런 완전히 똑같군요.

 

 

그럼 이렇게 결론 내릴 수 있을까요? new 연산자는 operator new 함수를 호출 한 후, 생성자를 호출 해 주는 연산자이다.

 

그런데 이게 또 아닌거 같습니다. 왜냐면 이 두 함수에는 VMT(Virtual Methor Table) 을 생성 해 주는 부분이 없거든요. 가상함수가 한 개 이상 존재하고 상속관계가 있는 클래스(상속 받았던 상속 했던) 에는 반드시 VMT의 포인터가 존재합니다. 그럼 이 VMT는 언제 등록되었을까요? 살짝 코드를 고쳐보았습니다.

 

#include <stdio.h>

#include <stdlib.h>

 

class Test

{

public:

           int a;

 

           void* operator new(size_t size)

           {

                     printf("한 개 할당중\n");

                     Test* temp = (Test*)malloc(size);

                     return temp;

           }

           Test()

           {

                     printf("Test Constructor\n");

                     func();

           }

 

           virtual void func()

           {

                     printf("Test::func()\n");

           }

};

 

class Test2 : public Test

{

           virtual void func()

           {

                     printf("Test2::func()\n");

           }

};

int main()

{

           Test* t1;

 

           t1 = new Test2;

 

           system("pause");

           return 0;

}

 

 

생성자에서 func라는 가상함수를 호출 하고 있습니다.

우리는 Test2를 생성하였으므로 Test2::func() 가 출력 될 거라고 기대 할 수 있겠습니다. 결과를볼까요?

 

image4.png

 

어라 뭔가 이상합니다. Test::func() 가 출력되었네요. 이게 어찌 된 일일까요?

그 이유는 생성자를 호출 하는 시점에서는 VMT의 포인터가 제대로 등록 되지 않기 때문에, 가상함수 본래의 역할을 제대로 하지 못하는 겁니다. 디스어셈블 한 코드를 보겠습니다.

 

image5.png

 

생성자를 호출 한 다음에도 추가적인 작업을 하고 있습니다.

그 중 빨간 네모로 표시 된 부분이 가상함수가 없을때는 존재하지 않던 부분입니다.

즉 저 부분에서 VMT포인터를 추가하는 작업을 하고 있다고 생각 할 수 있겠습니다.

 

이제 new 의 진실이 밝혀졋군요.

new 연산자를 호출하면

 

1.     메모리 할당을 위해 operator  new 함수를 호출한다

2.     생성자를 호출한다

3.     VMT를 등록해 준다

 

3가지 과정으로 new 의 역할은 모두 종료됩니다.

쉽고 편하게 쓰던 연산자가 참 하는 일도 많네요 : )

 

그럼 또 다른 언어인 Delphi 의 경우는 어떨까요?

 

program Project2;

 

{$APPTYPE CONSOLE}

 

uses

  SysUtils;

 

type

  Test = class

  public

    a : Integer;

 

    procedure func;virtual;

    constructor Create;

  end;

 

  Test2 = class(Test)

  public

    procedure func;override;

  end;

 

constructor Test.Create;

begin

  func;

end;

 

procedure Test.func;

begin

  WriteLn('Test.Func');

end;

 

procedure Test2.func;

begin

  WriteLn('Test2.Func');

end;

 

var

  T : Test;

begin

  T := Test2.Create;

  ReadLn;

end.

 

출력 결과는 아래와 같습니다.

image6.png

 

Delphi는 생성자 호출 시점이 VMT 생성 시점보다 뒤입니다.

Delphi 에서는 생성자 내에서 가상함수를 호출하더라도 정상적으로 작동합니다.

?

Board Pagination Prev 1 ... 2 3 4 5 6 7 ... 8 Next
/ 8