아.....자꾸 까먹어요. 포인터에 대한 개념이 점점 사라지고 있는 느낌이네요-_-;

얼마전 동적할당을 할 일이 생겨서 포스팅해둡니다.










[code]#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM 2 /*  동적으로 할당할 수 */
#define LENGTH 80 /*  문자열길이 */

int main(void) {
 char **id;
 int i;
 
 id = (char **)malloc(NUM * sizeof(char *));
 for (i = 0; i < 2; i++) {
  id[i] = (char *)malloc(LENGTH * sizeof(char));
 }
 strcpy(id[0], "mudchobo");
 strcpy(id[1], "idoori");
 
 for (i = 0; i < 2; i++) {
  printf("%s\n", id[i]);
 }
 
 return EXIT_SUCCESS;
}
[/code]
아.....저렇게 하는 거군요-_-;

 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon 필유 2008.03.10 20:29  댓글주소  수정/삭제  댓글쓰기

    지나가다 보고 갑니다만... 사용후에는 free를 해줘야겠죠? ^^

  2. IRIS 2010.08.27 14:41  댓글주소  수정/삭제  댓글쓰기

    저도 지나가다 씁니다만..
    저건 엄연히 2차원 배열은 아닌겁니다.
    만약 2차원 배열이라면
    memset(array, 0, sizeof(array));
    의 구문으로 모든 배열 값들을 초기화할 수 있어야죠.
    (하지만 위 문장에 id를 넣었다가는 할당한 메모리만 날리는 꼴이 되겠지요.)
    즉 각 차원의 모든 요소들이 인접해야 'x차원 배열'이라고 부를 수 있는 겁니다.
    2차원 배열을 동적할당한다는 글을 보고 신기술인가? 깜짝놀라서 들어와봤네요. ㅎㅎ

    • mindbomb 2010.10.08 08:45  댓글주소  수정/삭제

      저 역시 지나가다..

      일반적으론 배열의 배열 형태로 2차원 배열을 동적할당하지만
      열의 크기가 고정되어 있다면 연속적인 2차원 배열의 동적할당이 가능합니다.

      예를들어
      int (*p)[3]= (int(*)[3])malloc(n*3*sizeof(int));
      이 경우
      n*3 크기의 연속적인 2차원 배열이 생성됩니다.
      p가 배열주소상수가 아니라 포인터변수이며 그때문에
      p가 가리키는 공간의 크기는 바인딩되어 있지 않다는 점을 빼곤
      int p[n][3]과 동일합니다.
      (memset(p,0,sizeof(p))형태로 초기화 못함, 허나 연속적이기 때문에 memset(p,0,n*3*sizeof(int))로는 초기화 가능.)




      참고로 배열과 포인터의 차이를 말씀드리자면

      N*M크기의 순수한 2차원배열p가 있다고 할때
      p[y][x]=0;

      *(p+y*M*sizeof(int)+x*sizeof(int))=0;
      형태의 연산을 수행하는 어셈블코드로 생성되는데
      (이때 덧셈은 포인터 덧셈이 아니라 산술 덧셈인 것에 유의)
      소스코드 상엔 M값을 명시하지 않았음에도 배열을 선언한 순간 배열의 가로 M 크기가 결정되기 때문에 컴파일러는 이를 상수로 처리 할 수 있습니다.

      허나 p가 포인터의 포인터일 경우
      p[y][x]=0;은 (p[y])[x]=0;으로써 다음과 같이 변환됩니다.(이때 덧셈은 포인터 덧셈이 아니라 산술 덧셈인 것에 유의)
      *(*(p+y*sizeof(int*))+x*sizeof(int))=0;


      다음과 같은 코드가 에러가 나는 이유는 이런 차이에서 오는 것이라 할 수 있죠...
      int a[3][3];
      int **p;
      int *p2[3];
      p=a; //컴파일에러:인덱스 처리 방법이 다르므로 2차원 배열 주소를 포인터의 포인터로 형변환 할 수 없음.
      p2=a; //OK:에러발생안함
      p2[y][x]는 (p2[y])[x]으로.. 괄호 안부분은 포인터의 인덱스계산방식, 괄호바깥쪽은 배열의 인덱스계산방식을 따르게 됨. 따라서 p2[y][x]의 주소는 (p+y*sizeof(int[3]))+x*sizeof(int)로 계산되고,
      a[y][x]는 p+y*3*sizeof(int)+x*sizeof(int)로 계산되는데... 이때 sizeof(int[3])과 3*sizeof(int)는 같은 값을 가지므로 동일한 인덱스 계산법인셈. 따라서 형변환이 가능함.

    • 머드초보 2010.11.05 19:28  댓글주소  수정/삭제

      아흑.....
      좋은 강의 감사합니다ㅠㅠ
      제가 c언어는 잘 몰라서ㅠㅠ
      감사해요~