Development of Fashion CAD System 6. Pointer and Memory Sungmin Kim SEOUL NATIONAL UNIVERSITY Pointer and Memory Topics 포인터 변수와 포인터의 의미 Pass-by-Value 와 Pass-by-Reference 메모리 포인터와 배열 고정된 크기의 배열 정의 크기가 변하는 배열 정의 다차원 배열 정의 2
Pointer C 언어에서의변수 변수의정의 프로그래밍언어의기초가되는개념 어떤값을대입할수있는대상 변수의종류 기본형 정수형 short, unsigned short, int, unsigned int, long, unsigned long 실수형 float, double, long lobule 문자형 char, unsigned char 무 형 void 구조형 배열 [ ] 구조체 struct 공용체 union 3 Pointer C 언어에서의포인터 포인터의정의 Memory 변수가저장되어있는메모리의주소 (address) 메모리의주소도변수 16비트, 32비트, 64비트 CPU 의의미 중요성 동적 (dynamic) 메모리할당 대량의데이터에대한빠른참조 (reference) 가가능 향상된자료구조의설계 Linked list Binary tree 변수 A 의주소 배열 B 의주소 1234 1 2 3 4 5 4
Pointer C 언어에서의포인터 Pass by Value 함수에어떤인자를넘겨줄때복사본을만들어서넘겨주는방법 함수내부에서인자의값을변경하더라도원본은변하지않는다 대량의데이터를넘겨줘야할경우메모리가낭비된다 Pass by Reference 함수에어떤인자를넘겨줄때인자의포인터를넘겨주는방법 함수내부에서인자의값을변경하면바로원본이변경됨 대량의데이터를주고받기편함 변수를지정할때타입에관계없이일정한메모리만소요됨» 16비트, 32비트, 64비트등주소체계에따름 5 Memory 동적메모리할당 정적메모리할당 (Static Memory Allocation) 지금까지해왔던크기가고정된배열의정의 int x[10],y[10]; : 10개의 integer로된 x, y 배열 float number[100]; : 100개의 float으로된 number 배열 동적메모리할당 (Dynamic Memory Allocation) 배열의크기가정해져있지않은경우 int *x,*y; // 두개의 integer 배열의 pointer float *number; // float 배열의 pointer '*' 연산자는해당변수의 ' 주소 ', 즉 pointer 의미 필요한크기만큼의 memory block 을잡은다음 pointer 에그주소를대입하면됨 사용이끝난메모리는반드시해제해야함 free(x); free(y); 6
Memory 동적메모리할당 Operating System의역할 Memory block 의할당은 O/S 의주요역할중하나 주기억장치 (RAM) 는물론보조기억장치 (HDD, SSD) 에걸쳐안정적인메모리를할당해야함 C 에서의 memory 할당 #include <stdlib.h> calloc ( 최초할당 ), realloc ( 크기조절재할당 ) 함수를사용 int *x=(int*)calloc(10,sizeof(int)); x=(int*)realloc(x,sizeof(int)*100); free(x); C++ 에서의 memory 할당 new 연산자 TPoint *p=new TPoint[100]; delete []p; 7 Memory 동적메모리할당 calloc 함수원형 void* calloc(count, size); 리턴값은물리적주소이며지정하고자하는변수형으로 cast 해줘야함 첫번째인자는할당할배열의크기 두번째인자는배열의한요소의크기» O/S 나 machine에따라 integer 는 4 바이트일수도, 8 바이트일수도있음 realloc 함수원형 void* realloc(void* memory_block, size); 리턴값은물리적주소이며지정하고자하는변수형으로 cast 해줘야함 첫번째인자는크기를조절할대상포인터 두번째인자는조절후의크기 8
Points Point 관련소스수정 TChildForm.h Pointer 는 struct 에도당연히적용가능 int ptpoint PointNum; *Point; TChildForm.cpp 최초에포인터를초기화해야함 PointNum=0; Point=0; OnClose event handler 에서는할당된메모리를해제해야함 void fastcall TChildForm::FormClose(TObject *Sender, TCloseAction &Action) if (Point) free(point); Point=0; Action=caFree; 9 Points Point 관련소스수정 점을추가하는함수가필요 void fastcall TChildForm::AddXY1Click(TObject *Sender) PointXYDialog->ShowModal(); if (PointXYDialog->Result==1) Point[PointNum].x=PointXYDialog->X->Text.ToDouble(); Point[PointNum].y=PointXYDialog->Y->Text.ToDouble(); PointNum++; void fastcall TChildForm::AddXY1Click(TObject *Sender) PointXYDialog->ShowModal(); if (PointXYDialog->Result==1) AddPoint(PointXYDialog->X->Text.ToDouble(), PointXYDialog->Y->Text.ToDouble(); 10
Points Point 관련소스수정 AddPoint 함수정의 void fastcall TChildForm::AddPoint(float x,float y) Point=(ptPoint*)realloc(Point,sizeof(ptPoint)*(PointNum+1)); Point[PointNum].x=x; Point[PointNum].y=y; PointNum++; Move Point 메뉴핸들러수정 void fastcall TChildForm::MovePoint1Click(TObject *Sender) if (Sel[i].Type==0) AddPoint(Point[Sel[i].Num].x+x,Point[Sel[i].Num].y+y); 11 Points Point 관련소스수정 Divide Point 메뉴핸들러수정 void fastcall TChildForm::AddDividePoint1Click(TObject *Sender) if (DividePointDialog->Result) float m=dividepointdialog->m->text.todouble(); float n=dividepointdialog->n->text.todouble(); AddPoint((m*Point[Sel[1].Num].x+n*Point[Sel[0].Num].x)/(m+n), (m*point[sel[1].num].y+n*point[sel[0].num].y)/(m+n)); Mirror Point 메뉴핸들러수정 void fastcall TChildForm::AddMirrorPoints1Click(TObject *Sender) for(i=1;i<selnum;i++) ptpoint p=mirrorpoint(a,b,point[sel[i].num]); AddPoint(p.x,p.y); 12
Lines Line 관련소스수정 배열선언수정및포인터초기화, 메모리해제 int ptline LineNum; *Line; LineNum=0; Line=0; void fastcall TChildForm::FormClose(TObject *Sender, TCloseAction &Action) if (Point) free(point); Point=0; if (Line) free(line); Line=0; Action=caFree; 13 Lines Line 관련소스수정 Polyline 메뉴핸들러수정 AddLine 함수정의 void fastcall TChildForm::Polyline1Click(TObject *Sender) for(i=0;i<selnum-1;i++) AddLine(Sel[i].Num,Sel[i+1].Num); Struct 의여러변수를쉽게초기화 void fastcall TChildForm::AddLine(int p1,int p2) Line=(ptLine*)realloc(Line,sizeof(ptLine)*(LineNum+1)); Line[LineNum].Type=0; // line Line[LineNum].Color=clBlack; Line[LineNum].Thickness=1; Line[LineNum].Style=0; Line[LineNum].PointNum=2; Line[LineNum].Point[0]=p1; Line[LineNum].Point[1]=p2; LineNum++; 14
Lines Line 관련소스수정 Bezier Curve 메뉴핸들러수정 void fastcall TChildForm::BezierCurve1Click(TObject *Sender) AddBezierCurve(Sel); AddBezierCurve 함수정의 Pass-by-Reference 로 ptselection 구조체배열을전달 void fastcall TChildForm::AddBezierCurve(ptSelection *S) Line[LineNum].Type=1; // berizer curve Line[LineNum].Color=clBlack; Line[LineNum].Thickness=1; Line[LineNum].Style=0; Line[LineNum].PointNum=4; int i; for(i=0;i<4;i++) Line[LineNum].Point[i]=S[i].Num; LineNum++; 15 Patterns Pattern 관련소스수정 배열선언수정및포인터초기화, 메모리해제 int ptpattern PatternNum; *Pattern; PatternNum=0; Pattern=0; void fastcall TChildForm::FormClose(TObject *Sender,TCloseAction &Action) if (Point) free(point); Point=0; if (Line) free(line); Line=0; if (Pattern) free(pattern); Pattern=0; Action=caFree; 16
Patterns Pattern 관련소스수정 Define 메뉴핸들러수정 void fastcall TChildForm::Define1Click(TObject *Sender) if (!SelNum) return; int i; AddPattern("Pattern-"+AnsiString(PatternNum+1)); 17 Patterns Pattern 관련소스수정 AddPattern 함수의정의 void fastcall TChildForm::AddPattern(AnsiString N) Pattern=(ptPattern*)realloc(Pattern,sizeof(ptPattern)*(PatternNum+1)); for(i=0;i<selnum;i++) if (Sel[i].Type==1) Pattern[PatternNum].Line[Pattern[PatternNum].LineNum++]=Sel[i].Num; for(j=0;j<line[sel[i].num].pointnum;j++) AddPatternPoint(PatternNum,Line[Sel[i].Num].Point[j]); Pattern[PatternNum].Center=FindPatternCenter(PatternNum); PatternNum++; Line 의갯수도바꿀수있어야한다 결국전부 pointer 로바꿔야함 18
Patterns Pattern 관련소스수정 FindPatternCenter 함수의수정 Pattern 의포인터를전달 Return 값이불필요해짐 void fastcall TChildForm::AddPattern(AnsiString N) FindPatternCenter(Pattern[PatternNum]); PatternNum++; void fastcall TChildForm::FindPatternCenter(ptPattern &P) int i,j; P.mx=P.my=10000; P.Mx=P.My=-10000; float x,y; for(i=0;i<p.pointnum;i++) x=point[p.point[i]].x; y=point[p.point[i]].y; if (x<p.mx) P.mx=x; if (x>p.mx) P.Mx=x; if (y<p.my) P.my=y; if (y>p.my) P.My=y; P.Center.x=(P.mx+P.Mx)/2; P.Center.y=(P.my+P.My)/2; 19 Selections Selection 관련소스수정 배열선언수정및포인터초기화, 메모리해제 int ptselection SelNum; *Sel SelNum=0; Sel=0; void fastcall TChildForm::FormClose(TObject *Sender,TCloseAction &Action) if (Point) free(point); Point=0; if (Line) free(line); Line=0; if (Pattern) free(pattern); Pattern=0; if (Sel) free(sel); Sel=0; Action=caFree; 20
Selections Selection 관련소스수정 MouseDown 이벤트핸들러수정 void fastcall TChildForm::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) if (!DragStart) if (Shift.Contains(ssCtrl)) int o=findobject(x,y); if (!Shift.Contains(ssShift)) SelNum=0; if (Sel) free(sel); Sel=0; if (o!=-1) AddSelection(ObjectType,o); else DragStart=true; if (Button==mbRight) Zooming=true; else Zooming=false; Start.x=(float)X; Start.y=(float)Y; void fastcall TChildForm::AddSelection(int type,int object) Sel=(ptSelection*)realloc(Sel,sizeof(ptSelection)*(SelNum+1)); Sel[SelNum].Type=type; Sel[SelNum].Num=object; SelNum++; 21 Problems Conventional Programming 의문제점 메모리할당의문제 동적할당된구조체내부에서또다시동적할당을하려면? 코드가독성의문제 이렇게복잡한코드가과연합리적인가? 코드중복의문제 같은코드가계속나와도되는건가? 코드재사용의문제 비슷한코드를다른프로그램에서쓸수있을까? UI 와데이터의분리문제 다른 UI 를쓰는프로그램으로바꿀수있을까? 디버깅의문제 수많은전역변수로엮인프로그램을과연디버깅할수있을까? 22