Difference between r1.8 and the current
@@ -81,14 +81,14 @@
return d;
}
}}}
1. Source 는 반드시 null terminate해주어야 한다. 그렇지 않으면 동작이 보장되지 않는다.
1. Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다.
1. multi-byte 에 대한 고려는 정의하지 않는다.
1. Source 문자열의 길이를 반환한다.
* Destination 보다 반환 값(Source)이 큰 경우 복사된 문자열은 잘린 형태가 된다는 의미
size_t strlcpy(char *d, const char *s, size_t dn)
{
}
}}}
=== [*strlcpy https://man.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3] ===
=== strlcpy ===
1. Destination의 null terminate를 보장해준다.1. Source 는 반드시 null terminate해주어야 한다. 그렇지 않으면 동작이 보장되지 않는다.
1. Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다.
1. multi-byte 에 대한 고려는 정의하지 않는다.
1. Source 문자열의 길이를 반환한다.
* Destination 보다 반환 값(Source)이 큰 경우 복사된 문자열은 잘린 형태가 된다는 의미
1. 구현은 다음과 같거나 유사한 행동을 할것이다.
1. 구현은 다음과 같거나 유사한 행동을 할것이다. (참고: [^https://man.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3])
{{{#!enscript csize_t strlcpy(char *d, const char *s, size_t dn)
{
@@ -105,5 +105,4 @@
return sl;
}
}}}
}
}}}
strcpy_s에 대해서
- 작성자
- 고친과정
2011년 2월 12일 : 처음씀
1.1. 개요
예전 VisualStudio 버젼에서는 정상적으로 strcpy 표준함수를 사용할수 있었으나 요즘에는 strcpy 를 사용하면 경고를 내보냅니다.
물론 무시할수 있지만 무시하자니 경고누적으로 불안감이 증가하죠...
그래서 울며겨자먹기로 잘 설계된 코드마저도 MS의 강제적인 비표준안으로 코드를 수정해야 합니다.
게다가 이렇게 수정하면 다른운영체제로 포팅할때도 다 수정해주어야 합니다.
참 안좋은 상태만 만들어 가네요.
어쨌건 strcpy, strncpy를 strcpy_s로 바꾸는 작업을 할수밖에 없는데
문제는 기존 코드를 아무생각없이 바꾸었다가는 낭패를 볼수 있습니다.
그래서 정리합니다. strcpy_s와 strncpy는 같은 치환레벨이 아니라는 점을 말입니다.
strncpy로 된 부분을 strcpy_s 로 치환하기 위해서는 크게 문제시 되는것은 두가지 입니다.
하나는 인자의 위치가 다르다는 점이고 또 다른 하나는 Source에 주어지는 문자열이 반드시 Null terminate되어야 한다는 점입니다.
Null terminate되지 않은 경우 일부 Window version에서는 예외가 발생되는데 또 어떤 버젼에서는 잘 돌아간다는 점입니다.
strcpy_s 와 strncpy함수는 동일한 목적의 함수가 아니라는 점을 인지해야 합니다.
물론 무시할수 있지만 무시하자니 경고누적으로 불안감이 증가하죠...
그래서 울며겨자먹기로 잘 설계된 코드마저도 MS의 강제적인 비표준안으로 코드를 수정해야 합니다.
게다가 이렇게 수정하면 다른운영체제로 포팅할때도 다 수정해주어야 합니다.
참 안좋은 상태만 만들어 가네요.
어쨌건 strcpy, strncpy를 strcpy_s로 바꾸는 작업을 할수밖에 없는데
문제는 기존 코드를 아무생각없이 바꾸었다가는 낭패를 볼수 있습니다.
그래서 정리합니다. strcpy_s와 strncpy는 같은 치환레벨이 아니라는 점을 말입니다.
strncpy로 된 부분을 strcpy_s 로 치환하기 위해서는 크게 문제시 되는것은 두가지 입니다.
하나는 인자의 위치가 다르다는 점이고 또 다른 하나는 Source에 주어지는 문자열이 반드시 Null terminate되어야 한다는 점입니다.
Null terminate되지 않은 경우 일부 Window version에서는 예외가 발생되는데 또 어떤 버젼에서는 잘 돌아간다는 점입니다.
strcpy_s 와 strncpy함수는 동일한 목적의 함수가 아니라는 점을 인지해야 합니다.
1.2. strcpy_s
- Destination의 null terminate를 보장해준다.
- Source 는 반드시 null terminate해주어야 한다. 그렇지 않으면 동작이 보장되지 않는다.
- Size를 0 또는 그보다 작은크기대역으로 주면 error를 반환한다.
- Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다.
- Destination과 Source는 어느한쪽이라도 NULL이면 error를 반환한다.
- multi-byte지원한다.
- 구현은 다음과 같거나 유사한 행동을 할것이다.
errno_t strcpy_s(char *d, size_t dn, const char *s) { size_t cn; size_t c; if(d == NULL || s == NULL) { return(EINVAL); } if(dn <= ((size_t)0u)) { return(ERANGE); } --dn; cn = strlen(s /* s가 null terminate되지 않으면 동작이 보장되지 못한다. */); cn = (dn <= cn) ? dn : cn; for(c = 0;c < cn;c++) { d[c] = s[c]; } d[c] = '\0'; /* null terminate 보장 */ return 0; }
1.3. strncpy
- Destination의 null terminate를 보장하지 않는다.
- Source는 null terminate가 아닌 경우도 허용한다. 그렇지만 이 경우 Size보다 Source공간이 적은 경우 동작이 보장될수 없다.
- Size가 0인 경우도 허용한다. 이 경우 아무 동작도 안한다.
- Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다.
- Destination과 Source는 어느한쪽이라도 NULL이면 동작을 보장할수 없다.
- multi-byte 에 대한 고려는 정의하지 않는다.
- 구현은 다음과 같거나 동등한 행동을 할것이다.
char *strncpy(char *d, const char *s, size_t dn) { size_t c; /* d 와 s중 하나라도 NULL인 경우 어떤일이 벌어질지 정의되지 않는다. */ for(c = 0;c < dn && s[c] != '\0';c++) { d[c] = s[c]; } for(;c < dn;c++) { d[c] = '\0'; } return d; }
1.4. strlcpy
- Destination의 null terminate를 보장해준다.
- Source 는 반드시 null terminate해주어야 한다. 그렇지 않으면 동작이 보장되지 않는다.
- Destination과 Source의 메모리 영역이 겹치면 의도하지 않는 동작이 일어날수 있다.
- multi-byte 에 대한 고려는 정의하지 않는다.
- Source 문자열의 길이를 반환한다.
- Destination 보다 반환 값(Source)이 큰 경우 복사된 문자열은 잘린 형태가 된다는 의미
- 구현은 다음과 같거나 유사한 행동을 할것이다. (참고: https://man.freebsd.org/cgi/man.cgi?query=strlcpy&sektion=3)
size_t strlcpy(char *d, const char *s, size_t dn) { size_t sl = strlen(s /* s가 null terminate되지 않으면 동작이 보장되지 못한다. */); size_t cn, c; if (dn-- > 0) { cn = (dn <= sl) ? dn : sl; for(c = 0;c < cn;c++) { d[c] = s[c]; } d[c] = '\0'; /* null terminate 보장 */ } return sl; }