2009-08-11 3 views
2

제목에서 언급했듯이 목표는 표준 라이브러리 함수 나 첨자를 사용하지 않고 C 스타일 문자열을 메모리에 복사하는 것입니다. 여기Dereference 만 사용하여 무료 스토어에 C 스타일의 문자열 복사

내가 문제가 할당 그냥 *p (p[0]에 해당하는) 전용 메모리에 문자 "H"를 할당하는 것입니다 분명히

#include "std_lib_facilities.h" 

char* strdup(const char* p) 
{ 
    int count = 0; 
    while (p[count]) ++count; 
    char* q = new char[count+1]; 
    for (int i = 0; i < count + 1; ++i) *(q + i) = *(p + i); 
} 

int main() 
{ 
    char word[] = "Happy"; 

    char* heap_str = strdup(word); 
} 

지금까지 [SOLVED]

을 것입니다. subscripting 또는 STL 함수없이 C 스타일의 문자열을 할당하는 방법을 잘 모르겠습니다.

+0

왜 라이브러리 함수 또는 하위 스크립트를 사용하지 않습니까? 사용할 라이브러리 함수 (strlen(), strcpy() 및/또는 memcpy())는 모두 매우 간단하게 구현할 수 있습니다. 확실히 당신이 그들을 사용하도록 허락받지 못한다면 (숙제?) 그것은 당신 자신의 임프레션을 해결하는 것이 매우 쉽습니다. –

+0

나는 스스로 가르치는 책에서 운동을한다. – trikker

+0

나는 스스로 학습하는 책이다. subscripting을 처리하기 위해 포인터 산술 연산을하고 있습니다. – trikker

답변

6

C 스타일 문자열은 '\ 0'으로 끝납니다. 얼마나 오래 있는지 알기 위해 '\ 0'을 만나기 전까지는 함수 문자 내의 문자열을 문자 단위로 횡단해야합니다. strlen()을 호출하면 효과적입니다. 문자열의 길이를 알면 길이가 + 1 인 올바른 크기의 메모리를 할당 할 수 있습니다 ('\ 0 ').

배열 p의 i 번째 요소에 액세스하려면 하나는 첨자 인 p[i]을 사용합니다.

p[i] 형태의 첨자는 C 표준 (C99의 6.5.2.1)과 C++ 표준 (C99의 5.2.1) 모두에 의해 공식적으로 *((p)+(i))으로 정의됩니다. 여기서 p 또는 i 중 하나는 T에 대한 포인터 유형이고 다른 하나는 정수 유형 (또는 C++의 열거 형)입니다. 배열 이름은 자동으로 (어쨌든 대부분의 사용 유형에서) 해당 배열의 첫 번째 요소에 대한 포인터로 변환되기 때문에 p[i]은 배열 p의 i 번째 요소입니다.

기본 산술처럼 ((p)+(i))은 포인터 연산에서 ((i)+(p))과 같습니다. 즉, *((p)+(i))*((i)+(p))과 같습니다. p[i]i[p]과 동일합니다.

+0

이제 그의 유일한 문제는'[] '을 사용하지 않고 이것을 수행하는 방법을 찾는 것입니다. 좋은 운동. – dmckee

+0

네, 문자열 길이를 알아야 할 필요가 있다고 생각했습니다. 그러나 메모리 양을 할당 할 수 있다고해도 문자열을 메모리에 저장해야합니다. 내가 문자열 길이를 알고 있다면 이것은 내가 할 일이다. for (int i = 0; i trikker

+0

p [i]는 * (p + i)와 동일합니다 – KTC

1

글쎄, 이것은 스스로 가르치는 연습이기 때문에, 아래 첨자와 포인터 산술 사이의 동등성에 대한 KTC의 좋은 설명과 비교/대비 될 수있는 대안을 살펴보십시오.

표준 라이브러리 기능이나 하위 스크립트를 사용하지 않고 strdup() 함수를 구현하는 것 같습니다.

malloc()에 대해 예외를 만들겠습니다. 위의 방법을 사용하지 않고 위의 작업을 수행 할 수있는 합리적인 방법이 없으므로 사용하는 것이 무엇을 가르치는 것에 해가되지 않습니다.

첫째, 우리는 라이브러리에서 사용할 수있는 것과 비슷 함수 호출의이 strdup()의 기본 구현을하자 :

size_t myStrlen(char* s) 
{ 
    size_t len = 0; 

    while (*s != '\0') { /* when s points to a '\0' character, we're at the end of the string */ 
     len += 1; 

     s += 1; /* move the pointer to the next character */ 
    } 

    return len; 
} 


void myStrcpy(char* dst, char* src) 
{ 
    while (*src != '\0') { /* when src points to a '\0' character, we're at the end of the string */ 
     *dst = *src; 

     ++dst; /* move both pointers to next character location */ 
     ++src; 
    } 

    *dst = '\0'; /* make sure the destination string is properly terminated */ 
} 
을 : 첨자없이

size_t myStrlen(char* s); 
void myStrcpy(char* dst, char* src); 

char* strdup(char* p) 
{ 
    size_t len = myStrlen(p); 

    char* dup = (char*) malloc(len + 1); /* include space for the termination character */ 

    if (dup) { 
     myStrcpy(dup, p); 
    } 

    return dup; 
} 

지금 작업자의 기능을 구현할 수 있습니다을

그리고 거기 있습니다. 이것은 할당의 조건을 만족시키고 첨자를 사용하는 대신 데이터 항목 배열을 통해 포인터를 조작 할 수있는 방법을 보여줍니다. 물론 myStrlen()myStrcpy() 루틴에 대한 논리는 원하는 경우 인라인으로 이동할 수 있으며 데이터를 복사하는 표현식에서 포인터 증가가 발생할 수있는 관용적 인 표현이 더 많이 사용될 수 있습니다 (하지만 초보자에게는 혼란 스럽습니다).