출처 : http://ngpiki.ngps.net/index.php?display=프로그래밍%20조각지식
프로그래밍 조각지식
malloc & calloc
일반적으로 C++이 도입되면서 malloc 과 free라는 함수의 사용빈도는 많이 줄어들고 있지만 클래스 기반이 아닌 오리지널 C나 C/C++의 중간 개념적인 소스의 경우 여전히 malloc와 free에 의해 메모리 할당, 해제를 하게 됩니다.(개인적으로는 malloc가 더 편하다는 -_-;;)
malloc라는 함수의 존재를 알고 있으면서도 calloc라는 함수에 대해선 모르고 지나치는 사람들이 많이 있는데 malloc와 calloc는 같은 맥락의 함수이지만 약간의 차이점을 가지고 있습니다.
malloc는 지정된 크기만큼의 메모리를 할당하지만 그 메모리 자체가 초기화 되어지지 않은체로 그저 공간만이 할당되는 역할을 하는 반면 calloc는 malloc과 마찮가지로 지정된 크기만큼의 메모리를 할당하면서 할당된 메모리를 모두 0으로 체워서 반환합니다. 간단하게 말하면 malloc 와 memset 을 (또는 bzero ) 한번에 사용 해 놓은 것이죠.
단, malloc 보다는 calloc 가 조금 더 느리다고 합니다.
TODO 메크로
헤더에 다음과 같은 메크로를 추가해 놓습니다.
#define LINE1(x) #x
#define LINE(x) LINE1(x)
#define TODO(msg) message ( __FILE__"(" LINE(__LINE__) "): [TODO] " #msg )
#define NOTE(msg) message ( __FILE__"(" LINE(__LINE__) "): [NOTE] " #msg )
소스 파일에서 메크로 사용은 다음과 같습니다.
#pragma TODO( "여기에 적어 놓을 말을 적습니다." )
그리고 소스 파일에 다음에 해야할 일이나 특이사항들을 적어 두면 컴파일시 output 창에 나타납니다. 그리고 output창에 나온 메시지를 더블클릭하면 해당 라인으로 이동합니다. 급하게 메모해야할 일이 있으면 유용한 메크로가 되지 않을까 합니다.
fscanf()등 파일에서 읽기 작업을 할때 보통 이런식으로 많이 사용합니다. 이때 버퍼를 넘어서 입력값이 들어올 수 있습니다. 이는 입력수를 제한하여 오버플로우를 방지할 수 있습니다. 이런식으로 크기를 제한하여 사용하면 간단히 막을 수 있습니다. "%%%ds"를 간단히 설灼玖? 맨앞의 %%는 %로 만들기 위해 넣는 부분이고 다음의 %d는 사이즈 수를 받기 위한 부분입니다. 그리고 마지막 s를 넣어 format을 완성하는 것이죠. 위와 같이 하면 szFormat에는 "%255s"와 같은 값이 들어갑니다. 시작하기에 앞서 파일들이 읽기전용이면 이를 풀어줍니다. 1) 프로젝트 폴더에 있는(하위폴더 포함) *.scc 파일을 모두 삭제 합니다. 2) *.dsw 파일을 열어 Source Safe 정보를 삭제합니다. 이부분을 삭제합니다. 3) 모든 *.dsp 파일을 열어 Source Safe 정보를 삭제합니다. 이 부분을 삭제합니다. 1) 프로젝트 폴더에 있는(하위폴더 포함) *.scc 파일을 모두 삭제 합니다. 2) *.sln 파일을 열어 Source Safe 정보를 삭제한다. 이부분을 정확하게 찾아서 삭제합니다. 3) 모든 *.vcproj 파일을 열어 Source Safe 정보를 삭제한다. 이부분을 삭제합니다. 보통 뒤에 '>' 이게 있는데 이건 지우면 안됩니다. 정확하게 해당 부분만 지우세요. 배열크기(NHASH)와 해시 값에 곱해지는 값(MULTIPLIER)과 가능하면 데이터 값들이 서로 공통된 약수를 가지지 않도록 하여 균등하게 분산시킬 수 있게 한다. 그러므로 곱해지는 값을 소수로 잡는다. ASCII 스트링의 경우 31과 37이 좋다. 이 내용은 게임 개발자를 위한 C++ (민프레스, 서진택 저)에서 가져온 것입니다. 이렇게 할당하면 맨끝 인덱스가 고정되어야 하는 단점이 있다. 참고 가장 일반적인 방법이다. 이 방법이 가장 이해하기 쉽다. 하나의 일차원 배열을 렙퍼하는 형식의 클래스를 만들고 그 클래스를 또 일차원 배열로 만들면 관리하기 편하고 조금 더 직관적인 코드를 만들 수 있다. 참고 크리티컬세션을 사용할때 이말을 상기하자. "크리티컬세션은 코드에 거는 것이 아니라 리소스에 거는 것이다." "이중 크리티컬 세션은 되도록 사용하지 말라. 데드락의 위험이 있다. 혹시 사용하게 된다면 모든 곳에서 각 크리티컬 세션을 똑같은 순서로 Lock하고 UnLock하게 하라." typename 키워드는 다음에 나오는 식별자가 타입이라는 것을 명시하기 위해 사용된다. 예를 보면, 여기서 typename은 SubType이 class T의 서브 타입이라는 사실을 명확하게 한다. 그래서 ptr 변수는 T::SubType 타입의 포인터가 된다. 물론 타입 T 안에 SubType가 정의 되어야 한다. typename 키워드를 빼버린다면, SubType는 static 변수로 간주된다. 그래서 붙이지 않을 경우 은 타입 T의 SubType static 변수와 ptr과 곱한 결과로 인식한다. 말이 안되는 것 같지만 컴파일러는 typename이 없다면 값으로 판단하기 때문에 반드시 필요하다. VC 6.0에서는 크게 문제가 없었지만, VC.NET 2003에서는 반드시 typename을 적어주어야한다. The Practice of Programming 라는 책에 보면 각 C와 C++의 연산이나 함수의 비용을 수만번 실행해서 평균값을 적어 놓은 것이 있습니다. 테스트를 250MHz MIPS R10000이라는 컴퓨터 사양으로 했다고 합니다. 컴퓨터가 일반적으로 사용하는 Intel x86이 아니라서 아쉽지만, 일단 참고삼아 볼 수 있고 궁금하면 테스트를 해보면 되니 여기에 적어 봅니다. (단위는 nanoseconds 입니다.) Int operations Float Operations Double Operations Numeric Conversions Integer Vector Operations Control Structures Input/Output Malloc String Functions String/Number Conversions Math Functions 만약 MS VC++에서 __int64를 printf() 등으로, 값을 출력하고자 할때 %d 로 출력을 하면 4바이트만 출력된다. 더욱 %d 뒤에 또 다시 %d 가 나왔을때 뒤 부분의 값은 올바르게 출력되지 않는다. 아마, %d 가 4바이트를 기준으로 끊어버리기 때문인 듯하다. 그럼 __int64 를(unsigned __int64 도 마찬가지 이다.) 출력하고자 한다면 64비트라는 것을 알려줘야 한다. 이것을 해주는 것이 MS VC++에서는 %I64d 이다 I64 가 64비트라는 것을 알려준다. 파일읽기 버퍼 오버플로우 방지 팁
FILE * fp = fopen( "test.dat", "r" ); if( fp == NULL ) return; fscanf( fp, "%s", szBuf );
fscanf( fp, "%255s", szBuf );
char szFormat[128];
sprintf( szFormat, "%%%ds", sizeof( szFormat )-1 );
fscanf( fp, szFormat, szBuf ); VC++ 프로젝트에서 Visual Source Safe 삭제 방법
VC++ 6.0 프로젝트에서 Visual Source Safe 삭제 방법
begin source code control ....(중략) end source code control
# PROP Scc_ProjName "(어쩌고저쩌고)" # PROP Scc_LocalPath "."
VC++ .NET 2003 프로젝트에서 Visual Source Safe 삭제 방법
GlobalSection(SourceCodeControl) = preSolution ...(중략) EndGlobalSection
SccProjectName="(어쩌고저쩌고)" SccLocalPath="."
스트링의 해시 값 구하기
enum { MULTIPLIER = 31 }; // or 37
unsigned int hash( char * str )
{
unsigned int h = 0;
// 해시 값이 양수가 되게 하기위해 unsigned char로 변환
unsigned char * p = NULL;
for( p = ( unsigned char * ) str; *p != '\0'; p++ )
h = MULTIPLIER * h + *p;
return (h % NHASH); }
http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-HashString&forum=totd&id=-1 2차원 배열 동적 할당
int (*pArray1)[3]; pArray1 = new int[2][3];
// ok delete [] pArray1; int (*pArray2)[3][4];
pArray2 = new int[2][3][4];
// ok delete [] pArray2; int (* pointer)3 => 크기가 3인 정수 배열의 배열의 시작주소 :
pointer + 1 == pointer1 int * pointer3 => int * 를 요소로 가지는 일차원 배열 double ** pData = NULL;
pData = new double*[nSize1];
for( int i = 0; i < nSize1; i++ ) pData[i] = new double[nSize2];
// ... for( int j = 0; j < nSize1; j++ ) delete [] pData[j];
delete [] pData; class CInt { public:
CInt( int nSize = 10 )
{ m_pArray = new int[nSize]; m_nSize = nSize; }
~CInt() { delete [] m_pArray; }
int & operator[]( int nIndex )
{ return m_pArray[nIndex]; }
private: int * m_pArray; int m_nSize; };
// main CInt * pInt; pInt = new CInt[3];
// ... pInt[i][j] 로 사용. delete [] pInt; 크리티컬세션을 사용할때 기억해야할 한마디
예)
csResource1.Lock();
csResource2.Lock();
...
csResource2.UnLock();
csResource1.UnLock();
...
/************
csResource2.Lock();
csResource1.Lock(); // 데드락 위험!!
**************/
csResource1.Lock();
csResource2.Lock();
...
csResource2.UnLock();
csResource1.UnLock(); typename 키워드
template< class T >
class MyClass {
typename T::SubType * ptr;
// ... }; T::SubType * ptr;
C와 C++의 비용 모델
i1++; 8 i1 = i2 + i3; 12 i1 = i2 - i3; 12 i1 = i2 * i3; 12 i1 = i2 / i3; 114 i1 = i2 % i3; 114 f1 = f2; 8 f1 = f2 + f3; 12 f1 = f2 - f3; 12 f1 = f2 * f3; 11 f1 = f2 / f3; 28 d1 = d2; 8 d1 = d2 + d3; 12 d1 = d2 - d3; 12 d1 = d2 * d3; 11 d1 = d2 / d3; 58 i1 = f1; 8 f1 = i1; 8 v[i] = i; 49 v[v[i]] = i; 81 v[v[v[i]]] = i; 100 if( i == 5 ) i1++; 4 if( i != 5 ) i1++; 12 while( i < 0 ) i1++; 3 i1 = sum1( i2 ); 57 i1 = sum2( i2, i3 ); 58 i1 = sum3( i2, i3, i4 ); 54 fput( s, fp ); 270 fgets( s, 9, fp ); 222 fprintf( fp, "%d\n", i ); 1820 fscanf( fp, "%d", &i1 ); 2070 free( malloc( 8 ) ); 342 strcpy( s, "0123456789" ); 157 i1 = strcmp( s, s ); 176 i1 = strcmp( s, "a123456789" ); 64 i1 = atoi( "12345" ); 402 sscanf( "12345", "%d", &i1 ); 2376 sprintf( s, "%d", i ); 1492 f1 = atof( "123.45" ); 4098 sscanf( "123.45", "%f", &f1 ); 6438 sprintf( s. "%6.2f", 123.45 ); 3902 i1 = rand(); 135 f1 = log( f2 ); 418 f1 = exp( f2 ); 462 f1 = sin( f2 ); 514 f1 = sqrt( f2 ); 112 MS VC++에서 __int64 값 출력하기
__int64 n64SumVal;
...
printf( "Val: %I64d", n64SumVal );
'개발ㅣ어플ㅣ회사 > 개발ㅣ기타ㅣQ & A' 카테고리의 다른 글
온라인으로 오라클 쿼리 테스트 해보기. (Oracle Online Query Test) (0) | 2012.02.06 |
---|---|
C++ 폴더체크하는 함수 (0) | 2009.03.23 |
C, C++에서 동적배열 생성하기 (0) | 2008.12.05 |
개발링크 모음 [펌] (0) | 2006.09.28 |
Boost Libraries (일부번역...) (0) | 2006.09.23 |