본문 바로가기

Programming/C language

Chapter 11. 메모리와 포인터 (문제풀이)

필수실습문제)


11-01) 중대한 두 가지 오류 


#include <stdio.h>

#include <stdlib.h>


int main(void) {

char szBuffer[12] = {"HelloWorld"};

char *pszData = NULL;


pszData = (char*)malloc( sizeof(char) * 12 );

pszData = szBuffer;

puts(pszData);


return 0;

}


이 예제를 작성하여 실행하면 실행결과가 잘 출력됨을 확인할 수 있습니다. 즉, 외형적으로나 결과적으로나 아무런 결함이 없어 보입니다. 

그러나 다음 코드는 두 가지 심각한 결함이 있습니다. 그 두 가지 결함이 무엇인지 답하고 문제가 없는 코드가 될 수 있도록 수정합니다. 



Q )

pszData 에는 malloc을 사용해 운영체제로부터 할당받은 12byte의 메모리 주소가 들어있었는데, pszData에 szBuffer의 주소를 대입해 

pszData에 저장되어 있던 12byte의 동적 메모리를 사용하지 못하게 되었다. 


또한 그 동적 메모리를 free()를 해서 해제를 해주어야 하는데, 이를 해제하지도 않고있다. 

(물론 이 상황에서 해제를 하면 동적할당 받은 메모리가 아니라 stack의 메모리를 해제하려고 하기때문에 error가 날 것이다.) 


pszData = szBuffer 부분을 memcpy(pszData, szBuffer, (sizeof(char) * 12)); 로 변경하면 된다. 




11-02) 문자열과 상대주소 계산


#include <stdio.h>

#include <string.h>


int main(void) {

char szBuffer[32] = {"You are a girl."};

char *pszData = szBuffer + 4;


printf("%c\n", szBuffer[0]);

printf("%c\n", pszData[0]);

printf("%c\n", pszData[6]);


printf("%s\n", szBuffer + 4);

printf("%s\n", pszData);

printf("%s\n", pszData + 4);

return 0;

}


다음 코드에서 배열 szBuffer의 메모리 구조를 그림으로 표현한 후, 예제의 실행결과를 작성합니다. 특히, 세 번째와 여섯 번째 printf() 함수의 출력 결과에 대해서는 왜 그런 결과가 출력되었는지 이유를 기술합니다. 



Q )

szBuffer의 메모리 주소를 0x0018FF20 이라고 가정하자. 그러면 You are a girl. 은 앞에서부터 0x0018FF20, 21, 22, 23 ... 순서일 것이다. 

pszData 에 szBuffer + 4를 대입 했는데 szBuffer는 char형이기 때문에 pszData에 저장되는 메모리 주소는 0x0018FF24가 될 것이다. 


순서대로 출력 결과를 살펴보자면 

szBuffer[0] : Y

pszData[0] : a

pszData[6] : g


위 경우에는 형식 문자열을 %c를 사용하기 때문에 인자로 char 형 데이터를 입력받는다. 그렇기에 배열[] 형태의 데이터를 입력해 주었다. 

szBuffer[0]의 경우 문자열의 첫 번째 문자인 Y가 출력되고

pszData[0]의 경우 0x0018FF24에 저장된 문자 a가 출력되고  

pszData[6]의 경우 0x0018FF24에서 6 더한 0x0018FF30 에 저장된 문자 g가 출력된다.



szBuffer + 4 : are a girl.

pszData : are a girl.

pszData + 4 : a girl.


위 경우에는 형식 문자열을 %s를 사용하기 때문에 인자로 char *형 데이터를 입력받는다. 그렇기에 배열의 이름을 입력해 주었다. 

szBuffer + 4의 경우 szBuffer의 기준주소인 0x0018FF20 + 4인 0x0018FF24에 저장된 a 부터 '\0'을 만날 때 까지 출력하므로 are a girl.을 출력한다.

pszData의 경우 0x0018FF24에 저장된 문자 a 부터 '\0'을 만날 때 까지 출력하므로 are a girl.을 출력하고

pszData + 4의 경우 pszData의 기준주소인 0x0018FF24 + 4인 0x0018FF28에 저장된 a 부터 '\0'을 만날 대 까지 a girl.을 출력한다. 






연습문제)


1)  int형 변수 nData가 선언되었다고 가정한다면, 소스코드에 기술된 'nData'와 '&nData'의 차이점이 무엇인지 

기술하세요. 


Q )

변수는 메모리에서 특정 영역에 할당된 메모리 공간을 의미한다. 

이러한 변수는 3가지 요소를 가지는데, 이 요소는 이름, 주소, 내용이다. 


nData만 기술하게 되면 이는 변수의 '내용'이 되고, 

&nData라고 기술하게 되면 이는 변수의 '주소'를 뜻하게된다. 




2)  매개변수로 char*형 자료를 받아서 문자열의 길이를 계산해 반환하는 함수를 작성하세요. 

함수의 이름은 GetLength()로 합니다. 



Q )





3) 다음 코드의 논리적 오류 두 가지는 무엇이고 어떻게 수정해야 하는지 기술하세요. 


- 필수실습문제 1번과 동일하므로 생략




4)  인터넷에서 strrev() 함수의 사용방법에 대해 찾아보고 이 함수와 동일한 기능을 수행할 수 있는 MyStrrev() 함수를 

작성 하세요.



Q )

strrev() 함수 원형 


char* strrev(char* string);


문자열의 기준주소 (char*)를 입력받아 문자열을 뒤집고 그 문자열의 주소를 반환하는 함수. 







5)  사용자로부터 입력받은 첫 번째 문자열을 동적 할당된 메모리에 저장한 후 화면에 출력하고, 

두 번째로 입력받은 문자열을 첫 번째로 동적 할당된 메모리에 덧붙여 출력하는 프로그램을 작성합니다. 

이때, 메모리가 부족해서 문제가 발생하지 않도록 메모리의 크기를 조정합니다. 

기존에 할당받은 메모리의 크기를 늘려도 좋고 다시 할당받아도 좋습니다. 

혹은 두 경우를 모두 구현하는 것도 좋습니다. 



Q )





6)  정수를 입력받고, 그 개수만큼 char*를 여러 개 저장할 수 있는 메모리를 동적 할당합니다.

그리고 입력할 문자열의 최대 길이를 입력받고, 최대 길이의 문자열을 저장할 수 있는 크기의 메모리를

동적 할당하여 입력받는 문자열을 저장한 후 출력하는 프로그램을 작성합니다. 



Q )


실행 결과




- 출처 : 독하게 시작하는 C 프로그래밍 (최호성, 루비 페이퍼)