//current - 리스트를 처음부터 끝까지 차례대로 검색할때 현재 위치.
//previous - 바로 전 위치.
//Next - 다음 위치.

#include < stdio.h >
#include < stdlib.h >

typedef struct _NODE{
  char ch;
  struct _NODE *next;
}NODE;

NODE *head;

void init(void);
void build(void);
void print(void);
void reverse(void);

int main(void){
  init();
  build();
  print();
  reverse();
  print();

  return 0;
}

void init(void){
  head = (NODE*)malloc(sizeof(NODE));
  head->next = NULL;
}

void build(void){
  NODE *tmp1, *tmp2, *tmp3, *tmp4;
 
  tmp1 = (NODE*)malloc(sizeof(NODE));
  tmp2 = (NODE*)malloc(sizeof(NODE));
  tmp3 = (NODE*)malloc(sizeof(NODE));
  tmp4 = (NODE*)malloc(sizeof(NODE));

  head->next = tmp1;
  tmp1->next = tmp2;
  tmp2->next = tmp3;
  tmp3->next = tmp4;
  tmp4->next = NULL;

  tmp1->ch = 'A';
  tmp2->ch = 'B';
  tmp3->ch = 'C';
  tmp4->ch = 'D';
}

void print(void){
  NODE *index;

  index = head->next;
  while(index !=NULL){
     printf("%c ", index->ch);
     index = index ->next;
  }
  printf("\n");
}

void reverse(void){
  NODE *index, *tmp, *tmp2;

  index = head->next->next;
  tmp = head->next;
  tmp2 = head;

  while(index->next != NULL){ //리버스 작업
     tmp->next = tmp2;
     tmp2 = tmp;
     tmp = index;
     index = index->next;
  }

  //마지막 작업
  tmp->next = tmp2;
  index->next = tmp;
  head->next->next = NULL;
  head->next = index;
}

Posted by 창신다이
y = (x + 3) & ~3;
Posted by 창신다이

수사 읽기

2006. 10. 18. 20:30

1. 연호 : 두자리씩 끊어서 읽음.
1965 : nineteen sixty - five

2. 시각 : 11 : 30 a.m. : eleven thirty a.m.

3. 전화번호 : 한자리씩 끊어 읽음
364 - 5195 : three six four,five one nine five

4. 온도계
25 C : twenty - five degrees Centigrade
80 F : eighty degrees Fahrenheit

5.소수
5. 37 : five point [decimal] three seven
0.205 : nought point [decimal] two nought five

6.날짜 June 5 : June (the) fifth, the fifth of June

7.왕호 Elizabeth Ⅱ : Elizabeth the second

8.분수
1/3 ; a third 3/4 ; three quarters, three - fourths
2/3 ; two - thirds 1/2 ; one half, a half

9. 기수의 서수 대용
Chapter Ⅱ ; chapter two, the second chapter
No. 3 : number three, the third number
World War Ⅱ ; World War two, the second World War

10. 기타 관용적 표현
+--------------------------------------------------------------------+
| by twos and threes (삼삼오오로) ten to one (십중 팔구) |
| in one's thirties (30대에) at first (처음에는) |
| in one's teens (10대에) for the first time (처음으로) |
| second to none (누구에게도 뒤지지 않은, 최고의) |
+--------------------------------------------------------------------+
☞ the third largest city = the largest city but two

Posted by 창신다이

주요 5형식 동사

2006. 10. 18. 20:29

1. make 류 [ O 를 C상태로 이르게 하다]
☞ make,keep, leave, call, name,elect,choose, appoint, paint, set, drive

2. think 류 [O가 C라고 생각하다]
☞ think, believe, find, know, consider
① 주로 <(to be) 형용사,명사>를 보어로 삼음
② <S + V + that >절로 고칠 수 있음

3. 지각동사 [ O가 C하는 것을 보다(느끼다 - -) ]
☞ see, watch, observe, hear, feel, smell

4. 사역동사 [ O에게 C 하도록 시키다]
☞ make, have, let + root
※ get, cause, drive + to - root

5. want류 [ O가 C하는 것을 원하다[명하다,허락,강요하다]]
☞ want, wish, like, order, ask, allow, compel,force,enable, persuade
주로 to + root를 목적어로 취함.

Posted by 창신다이

MC_knlAlloc 또는 MC_knlCalloc 으로 할당된 메모리를 MC_knlFree 로 해제 했다고 해서 완전히 해제되는 것이 아니며 MC_knlGetFreeMemory 를 호출하여 컴팩션을 해주어야 한다. 이 때 동적 할당된 메모리의 포인터가 바뀔 수 있으므로 할당된 메모리 포인터 이용시 MC_GETPTR 을 이용하여 다시 포인터를 얻어야 한다.

* 도움될만한 퍼온글 (www.mobilejava.com WIPI-C 게시판)

Q1. WIPI에서 Memory Compaction을 지원합니다. 이 COMPACTION이 Fragmentation을 줄이기 위한 일반 정렬 수준인지 아니면 정말 메모리를 절약할 수 있는 압축기술을 쓰는 것인지 궁 금합니다. 메모리가 정말 압축 될 것이라고 생각하기는 힘든데 혹시나 해서 여쭤봅니다.

A1. 제가 보기에는 WIPI에서 지원하는 Compaction은 Fragmentation을 줄이기 위한것 같네요. 여지껏 메모리를 압축하는것은 엄청난 기술이며... 여지껏 경험을 못해봤기 때문입니다. 그리고 압축하는거라면 거기에 따른 프로세싱 타임이 있어서 약간의 작업시간이 걸릴듯 하구요. 어쨌든 압축을 하기 위해 작업중에는 또 다른 공간이 필요함으로서 메모리를 더 쓰면 썼지... 절약은 되지 않는다고 봅니다... 다만 작업완료후에는 엄청나게 줄어들겠죠... 이래저래 디코딩이나 인코딩 하기 위해서는 추가 메모리 영역 사용 및 작업시간으로 손해를 보게 되는군요. 답변은 No입니다.

Q2. 수시로 Memory Compaction이 일어난다면 메모리 번지를 리턴받은 후 재사용할 때는 문제가 생길 수 있는건가요? 예를 들면 어플 초기화 단계에서 gLCDFrameBuffer = (WORD*)MC_GRP_GET_FRAME_BUFFER_POINTER(g_GrpFrameBuffer); 와 같이 gLCDFrameBuffer에 포인터를 리턴 받았다고 했을 때 일정 루틴을 실행 한 다음 gLCDFrameBuffer 값을 그대로 사용하면 Compaction으로 인한 메모리 주소가 변경이 생겨 심각한 문제가 생길 수 있는가 하는 것이지요. 만약 그렇다면 항상 MC_GRP_GET_FRAME_BUFFER_POINTER(g_GrpFrameBuffer); 이렇게 포인터를 받아 와야 하는 것인가요? 물론 Memory Compaction 기능이 지원되지만 수시로 이루어 지는 것이 아니라 개발자가 직접 명령을 내리는 것이라면 다르겠지만요.

A2. 사용자가 원하는 메모리 영역이 확보되어있다고 하지만 메모리가 Fragmentation 되어있다면... 메모리 할당은 이루어지지 않습니다. 이러한 상황을 해결하기 위한것이 Compaction 입니다. 이미 할당해 놓은 메모리 영역이 있음에도 불구하고 Compaction이 발생되게 되면 일단 미리 지정해놓은 메모리 포인터는 변경이 됩니다. 그리고 Compaction은 수시로 발생이 되나 발생되는 시점이 한정되어져 있습니다. 메모리 할당이라든지 메모리 재할당 등등... 대체적으로 메모리 사용 관련과 연관이 있죠. 그러기에 이부분에서만 실수를 안하시면 그렇게 문제는 안될것 같네요. 그리고 MC_knlCalloc 같은 메모리 할당을 했을시 넘어오는 ID값을 잘 생각하셔야 합니다. WIPI에서는 메모리 할당을 했을시 넘어오는 값이 포인터가 아닌 ID값이죠. 내부적으로 메모리 관리자가 있는듯 하구요. 거기에서 ID값에 맞는 포인터 값을 관리합니다. 그리고 메모리 할당을 한 포인터로 접근할시에 MC_GETDPTR 를 사용하여 ID값 전달후 넘어오는 포인터로 접근해서 사용하시면 될듯합니다. 그냥 메모리 포인터만으로 사용하시면 Compaction 이 발생한후에는 보관중이 포인터가 변경이 되기전 포인터이기에 다른 메모리영역 violation이 일어나게 됩니다. 그리고 내부적으로 Compaction은 자주 발생이 되며, 사용자가 MC_knlCalloc 하기전 메모리 영역이 확보가 되기 위한 작업으로 직접 Compaction을 내릴수 있습니다. MC_knlGetFreeMemory를 사용하여 메모리 할당전에 미리 Compaction을 발생시키는 거죠. 그러므로 사용자가 항상 Compaction이 일어났는지는 알길이 없다는겁니다. 그러기에 항상 포인터에 접근하실려면 Helper 함수를 통해 포인터를 매번 구해오셔야 합니다. 답변은 Yes입니다.

Posted by 창신다이

//No.1

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct _QPACKET {
int     nSize;
char  data[0];  //<--- 이 부분 data가 길어지더라도 시작 번지를 갖고 있는다
} QPACKET;


void aaa(int nSize, char *data)
{
QPACKET *test;
int a = 0;

a = sizeof(int);

test = (QPACKET*) malloc(sizeof(int) + strlen(data) + 1); //<--- 데이터의 길이 만큼 동적 메모리 할당

test->nSize = nSize;
strcpy(test->data, data);
printf("R: %s\n", test->data);

free(test);
}

void main(){
char data[12];
strcpy(data, "abcde");
aaa(strlen(data), data);
}


//No.2

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct _QPACKET {
int     nSize;
char  *data;  <---  이 부분
} QPACKET;

void aaa(int nSize, char *data)
{
QPACKET *test;
int a = 0;

a = sizeof(int);

test = (QPACKET*) malloc(sizeof(QPACKET));
test->data = (char *) malloc(strlen(data)+1);  <--- malloc 한 번더

if(test->data==NULL){
 printf("메모리 할당 실패\n");
}

test->nSize = nSize;
strcpy(test->data, data);
printf("R: %s\n", test->data);

free(test->data);
free(test);
}

void main(){
char data[12];
strcpy(data, "abcde");
aaa(strlen(data), data);
}

Posted by 창신다이
http://iampd.patzzi.com/media_view.asp?m=2659

김기사 일 고다꾸로 할거야?
Mr. Kim! Is that the best you can do?
Posted by 창신다이

변수를 선언하면 메모리에 공간이 확보된다.

값을 변수에저장하면 변수에 데이타가 쓰여진다. 하지만 메모리에 읽고쓰는건 느리다. 그에비해 CPU의 속도는 빠르다. 메모리와 CPU의 속도차이로 CPU의 성능을 제대로 활용하지 못한다. 그런데 CPU내부에 메모리처럼 사용할수 있는 공간이 약간존재하는 이 곳을 register라고 한다. 많이 사용되는 변수를 이곳에 저장하면 속도가 빠르다.

컴파일러가 컴파일을 할때 자동으로 최적화시켜주는데 그중하나가 자동으로 register에 등록하는것입니다. 수동으로 레지스터에 등록할려면
ex) int x; ===> register int x; 로해주지만 보통 2개정도로 적은수만 가능합니다.

volatile은 이와반대로 저런 최적화를 방지하기 위한 키워드 입니다.
즉 자동 최적화를 하지말라는것을 컴파일러에 알려주는겁니다.

왜냐면 저런 자동최적화가 문제를 발생시키는경우가 있기때문입니다. 그렇다고 최적화를 막으면 프로그램수행속도가 떨어집니다. 따라서 프로그래머가 원하는것만 최적화시키지 말것을 명령하는 것이 volatile 입니다.

예제) 사용법은 일반적인 변수타입선언과 같습니다.
volatile int x; 혹은 int volatile x 같은 의미입니다.
필요한경우는 memory-mapped I/O 혹은 스레드 같은 곳에서 사용됩니다.

Posted by 창신다이

BLOG main image
오랫동안 꿈을 그리는 사람은 마침내 그 꿈을 닮아 간다. -앙드레 말로- by 창신다이

공지사항

카테고리

분류 전체보기 (248)
공장이야기 (115)
Education (30)
회사이야기 (19)
일상 (73)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :