안녕하세요. 궁금증연구소 입니다.
오늘 포스팅 주제는 "동적할당 활용시 주의할점 (포인터보단 인덱스)" 입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * upper(char *ps);
main(){
char str[] = "apple Banana Grape";
char *pa;
pa = upper(str);
puts(pa);
free(pa);
}
char * upper(char *ps){
int n;
char *pa;
pa = (char*)malloc(sizeof(ps)+1); // 동적할당으로 받은 포인터 값을 계속 증가시켜 그 값을 리턴하면 안된다. pa는 보존해두는 방법을 써야 한다.(인덱스 활용)
n=0;
while(*ps){
if (*ps >= 'a' && *ps <= 'z'){
*pa++ = *ps - 32;
} else{
*pa++ = *ps;
}
ps++;
}
return pa
review1)
과일이름이 들어 있는 배열의 소문자 값을 대문자로 바꾸는 간단한 코드이다.
위 코드는 틀린 코드이다. upper 함수에서 동적할당으로 만든 pa 포인터 값을 증가시키면서 ps 포인터가 가리키는 과일문자 중 소문자를 대문자로 바꾸고 있다. 이때 리턴값을 증가된 pa 값을 넘겨주게 된다. 현재 pa가 가리키는 값은 동적할당으로 할당해둔 문자열포인터의 마지막+1 위치이다. 즉 쓰레기값을 출력할 수 밖에 없다.
review2)
위와 같은 경우는 index를 활용해서 pa의 초기값을 보존해 두는 방식을 쓰는것이 낫다. 혹은 초기값을 변수에 따로 저장해두고 초기값을 넘기는 방법도 생각해 볼 수 있겠다.
char * upper(char *ps){
int n;
char *pa;
pa = (char*)malloc(sizeof(ps)+1); // 동적할당으로 받은 포인터 값을 계속 증가시켜 그 값을 리턴하면 안된다. pa는 보존해두는 방법을 써야 한다.(인덱스 활용)
n=0;
while(*ps){
if (*ps >= 'a' && *ps <= 'z'){
pa[n++] = *ps - 32;
} else{
pa[n++] = *ps;
}
ps++;
review3)
포인터의 값을 연산하는 과정은 생각보다 복잡하기 때문에, *pa 연산을 여러번 하는 방식의 코딩은 좋지 않다. 따라서
ch = *ps++;
if( ch>='a' && ch<='z')
ch-=32;
pa[n++] = ch;
변수에 포인터연산을 담아두고, 변수를 활용하는 방식으로 하면 더 깔끔할 것 같다.
review4)
동적할당로 마련된 메모리에 "문자"를 일일히 넣어줄때는 반드시 끝에 NULL(0) 값을 넣어주는 것을 잃지 말아야 한다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * upper(char *ps);
main(){
char str[] = "apple Banana Grape";
char *pa;
pa = upper(str);
puts(pa);
free(pa);
}
char * upper(char *ps){
int n;
char *pa;
pa = (char*)malloc(sizeof(ps)+1);
n=0;
while(*ps){
char ch = *ps++;
if( ch>='a' && ch<='z')
ch-=32;
pa[n++] = ch;
}
pa[n]=0;
return pa;
}
위와 같이 쓰니 잘되었다. 끝.
[c언어] strcat 사용시 주의할점 (0) | 2022.07.19 |
---|---|
[c언어] strcpy 와 포인터 활용시 주의할 (0) | 2022.07.18 |
[c언어] 포인터와 배열을 같이 쓸때 주의 (0) | 2022.07.18 |
리눅스 변수 사용 주의할점~! (0) | 2022.07.12 |
c언어 0, '0' , '\0' 의 차이는? (0) | 2022.07.07 |