2010-01-24 8 views
0

gcc 4.4.2 c89문자 배열 복사

방금 ​​일부 포인터를 작업 중이었습니다. 그러나 아래의 프로그램을 사용하여 소스를 대상에 복사 할 수 없습니다. 비록 내가 루프에서 인쇄하고 인쇄 할 때 나는 소스에 문자를 표시 할 수 있지만 dest는 비어 있습니다. 포인터가 반환되면 대상이 비어 ​​있습니다. 그래서 아무 것도 복사하지 않았습니다.

나는 약 한 시간 동안이 문제를 겪어 왔으며 그 이유는 분명하지 않다.

제안 사항?

많은 감사,

char str_source[80] = "A string to be for demostration purposes"; 
char str_dest[80] = {0}; 

char *my_strncpy(char *dest, const char const *source, const size_t size) 
{ 
    size_t i = 0; 
    printf("size [ %d ]\n", size); 

    for(i = 0; i < size; i++) 
    { 
     printf("i [ %d ]\n", i); 

     *dest++ = *source++; 
     printf("*source++ [ %c ]\n", *source); 
     printf("*dest [ %c ]\n", *dest); 
    } 
    /* Null terminate */ 
    *dest++ = '\0'; 

    return dest; 
} 

=============== 편집

char str_source[80] = "A string to be for demostration purposes"; 
char str_dest[80] = {0}; 

printf("str_dest [ %s ]\n", my_strncpy(str_dest, str_source, sizeof(str_dest))); 


char *my_strncpy(char *dest, const char const *source, const size_t size) 
{ 
    size_t i = 0; 
    /* 
    * increment p and return the dest which will be 
    * the beginning of the array. 
    */ 
    char *p = dest; 

    /* Copy the specified amount (normally the max size of dest - 1) */ 
    for(i = 0; i < size; i++) 
    { 
    /* Ensure that the source is not overrun. */ 
    if(*source) 
     *p++ = *source++; 
    } 
    /* Null terminate */ 
    *p++ = '\0'; 

    return dest; 
} 

답변

4

정확히 당신이 기능이 작동하지 않습니다 테스트하는 방법 ? 함수가 dest을 반환하고 대상 버퍼의 을 가리키는 지 확인합니다. 호출 한 함수가 반환 된 포인터를 검사하고 있습니까? 아니면 대상 버퍼로 전달한 포인터를 확인하고 있습니까?

비슷한 이유로 인해 *destprintf은 쓸모가 없습니다. 당신은 이미 그 시점에서 dest을 증가 시켰으므로 다음은 미사용 위치를 가리키고 있습니다. (sourceprintf 호출은 또한 다음 문자, 당신은 방금 복사 안 하나를 복사 할 인쇄합니다.)를 같이

를 제외하고, 그것은 불분명 당신이되고 size을하려는 것. 대상 버퍼의 바이트 수를 경우 NUL 종료자를 쓸 때 버퍼 오버플로 수 있습니다.

오, 당신은 source 끝을지나 읽지 않았는지 확인해야합니다.

+0

이 경우 크기는 대상 문자열의 최대 크기입니다. 목적지가 오버런되지 않도록하십시오. 나는 당신의 교정으로 다시 편집했다. 그러나 사용자가 잘못된 크기를 전달하면이 함수가 손상 될 경우 책임을 질 수 없습니다. 이 100 % 바보 같은 증거를 만들 수 있을지 확신하지 못합니다. – ant2009

+0

@robUK : 아니요, 버퍼 오버플로가 발생합니다. 간단한 경우로 '크기'가 1이라고 가정합니다. 한 번 반복하고 'p'를 증가시킵니다. ''\ 0 ''을 쓸 때'p '는 목적지 버퍼의 끝을지나 한 원소를 가리킨다. 그리고 유효하지 않은 값 (아마도'size'가 0 일 때)에 대해서조차도, 버퍼 오버 플로우 대신 실패해야합니다. 그것이 착취가 시작되는 방법입니다. – jamesdlin

3

문제는 반환하는 포인터가 증가되어 시작을 가리 키지 않는 것입니다. 그래서 그것은 공란으로 보여줍니다. for 루프 인쇄의 경우에도 같은 결과가 나타납니다. 예를 들어

:

하는의이 최초 목적지 주소는 1000과 소스 문자열의 크기가 다음 destnation는 1020 반환하지만, 실제로 1000

초기를 저장하려고 반환해야한다, 20 가정 해 봅시다 주소를 로컬 변수에 저장하고이를 반환합니다.