2012-03-16 4 views
0

이중 포인터를 사용하고 포인터에 쓰는 함수에서 char 포인터에 대한 메모리를 할당하는 방법을 알고 싶습니다.C의 함수에서 이중 포인터를 사용하여 메모리를 할당하는 방법은 무엇입니까?

다음 코드를 작성하려고했지만 충돌이 발생합니다. 이것의 버그는 무엇입니까?

#include <stdio.h> 
void myfunc(const char* src, char** dest) 
{ 
    *dest = (char*)malloc(200); 
    while(*(*dest++) = (*src++ != '\0')); 
    *(*(++dest)) = '\0'; 
} 
void main() 
{ 
char* src = "hello"; 
char* dest = null; 
myfunc(src, &dest); 
printf("%s\n",dest); 
} 
+0

'dest'에는 데이터가 없습니다.먼저 유효한 데이터로 채우고 null로 종료되었는지 확인한 다음'=='연산을 수행하십시오. – Mahesh

+0

성취하려는 것은 무엇입니까? 그것은 경계 검사가없는 각각의 문자를 비교하려고 시도하는 것처럼 보이고,'malloc'을 수행 한 후에는 어떤 것도'dest'를 설정하지 않습니다. – Joe

+1

'char **'을 증가 시키면 다음'char *'를 가리키고 다음'char'는 가리 키지 않습니다. – sidyll

답변

3

당신은 대신 사본 루프 ('=='대 '=')의 루프를 비교 서면으로 작성했습니다, 당신은 당신이 쓰는 잘못된 포인터 증가됩니다

while(*(*dest++) == *src++); 

(추가를 라인 :

*(*(++dest)) = '\0'; 

는 질문에 대한 최신 정보 추가되었습니다 나는 모든 것을 분석하는 시도하려는 모르겠어요이 문제에 대한 해결책의 일부가 아닌 D를 참조하십시오... 아래 iscussion)

즉 올바른 얻을 수있는 가장 쉬운 방법은 아마도 다음과 같습니다.

char *tgt = *dest; 
while ((*tgt++ = *src++) != '\0') 
    ; 

우리는 나는)이 같은 짓 (단계에서 코드를 수정할 수 있습니다 :

static void myfunc(const char* src, char** dest) 
{ 
    *dest = (char *)malloc(200); 
    char *tgt = *dest; 
    while ((*(tgt++) = *(src++)) != '\0') 
     ; 
} 

이 parenthesises을 루프의 표현식을 완전히.

static void myfunc(const char* src, char** dest) 
{ 
    *dest = (char *)malloc(200); 
    char *tgt = *dest; 
    while ((*((*dest)++) = *(src++)) != '\0') 
     ; 
    printf("1: %s\n", tgt); 
} 

을 그리고 이것은 1: hello를 인쇄하지만, 메인 프로그램이 복사 된 문자열의 끝에서 당신이 *dest을 수정했기 때문에 그렇게는 NUL '\0'를 가리키는 빈 줄을 인쇄 : 우리는 지금 tgt에 대한 *dest을 대체 할 수 있습니다.

static void myfunc(const char* src, char** dest) 
{ 
    *dest = (char *)malloc(200); 
    char *tgt = *dest; 
    while ((*((*dest)++) = *(src++)) != '\0') 
     ; 
    printf("1: %s\n", tgt); 
    *dest = tgt; 
} 

을 그리고 main()는 정답을 인쇄합니다 : 그래서, 당신은해야 할 것입니다. 그러나 tgt ('대상'의 약자로, 보통 대상에 대해 dst을 사용하지만 그 값은 dest에 너무 가깝습니다.)을 사용하는 경우, 처음에는 *dest이 증가하는 복잡성을 피할 수 있습니다 .

사실, 당신은 사용을 고려해야합니다 :

#include <string.h> 

... 
strcpy(*dest, src); 

이 문자열을 복사 할 수 있습니다. strcpy()을 사용하면 '빠름', '더 간단'하고 명확하게 정확할 수 있습니다.


또한, 당신은해야합니다

#include <stdlib.h> 

malloc()를 선언 할 수 있습니다.

그리고 main()에 대한 올바른 반환 형식이 int입니다 :

C99에서
int main() 
{ 
    ... 
    return(0); 
} 

, 반환이 누락 된 경우 (유감스럽게도) 옵션 제로 (성공)을 가정 할 것이다; 이는 C++ 98의 동작과 일치합니다. 이전 버전의 C에서는 반환이 선택 사항이 아니 었습니다.

+0

strcpy없이 복사하는 방법을 알고 싶습니다. 동일한 기능과 이해를위한 탐구. – user1274081

0

작은 조각에 많은 문제가 있습니다. 어디서부터 시작해야할지 모르겠습니다 ... 코드를 불필요하게 복잡하게 만들었으므로 결국 버그가 가득 찼습니다. 이 코드는 임베디드 시스템을 위해, 또는 당신이 수술 시스템을 작성하지 않는 한, 주가 INT를 반환해야하지 않는 한

  • :

    상황이이 코드를 컴파일을 만들기 위해 수정합니다.

  • NULL은 C의 대문자 상수입니다. stddef.h 라이브러리에 있습니다.
  • malloc 함수는 반드시 포함되어야하는 stdlib.h에 있습니다.

심각한 버그 :

  • 은의 malloc의 결과를 캐스트하지 마십시오. C FAQthis SO post에 대한 자세한 정보
  • malloc에 ​​의해 할당 된 메모리를 항상 비우십시오.
  • * srC++! = '\ 0'의 부울 결과 (참/거짓)를 문자에 할당합니다. 버그로 연결

널리 인정 나쁜 & 위험한 연습 :

  • 항상 const를 같은 문자열 리터럴에 대한 포인터를 선언합니다.
  • 내부 조건을 절대로 사용하지 마십시오. (MISRA-C : 2004 13.1).
  • 복잡한 식 (+++ 12.13)에서 ++ 연산자를 절대로 사용하지 마십시오.
  • 루프 문을 포함하는 행의 끝에는 절대로 세미콜론을 넣지 마십시오. (MISRA-C : 2004 14.9)
  • 중괄호 {} 없이는 절대로 사용하지 마십시오 (MISRA-C : 2004 14.8).

불량 스타일 :

  • 주() 항상 반환해야합니다.
  • 특히 "malloc"에 매개 변수를 전달할 때 "마법 번호"를 사용하지 마십시오.
  • 항상 malloc()의 결과를 확인하십시오.

유용한 힌트 :

  • 은 calloc malloc을 달리 제로로 할당 된 메모리를 모두 설정한다. calloc을 사용하면 수동으로 0으로 설정할 필요가 없습니다.

고정 코드 :

#include <stdio.h> 
#include <stddef.h> 
#include <stdlib.h> 

#define DYNAMIC_BUF_SIZE 200 

void make_string (const char* src, char** dest) 
{ 
    *dest = calloc(DYNAMIC_BUF_SIZE, sizeof(char)); 

    if(*dest == NULL) 
    { 
    /* error handling here */ 
    } 

    char* dst = *dest; 
    *dst = *src; 

    while(*src != '\0') 
    { 
    dst++; 
    src++; 
    *dst = *src; 
    } 
} 

void delete_string (char* str) 
{ 
    free(str); 
} 

int main() 
{ 
    const char* src = "hello"; 
    char* dest = NULL; 

    make_string (src, &dest); 
    printf("%s\n",dest); 
    delete_string(dest); 

    return 0; 
} 

편집 : strcpy를하지 않고 새로운 버전(), 영업 이익의 요청에 따라.

0
//It seems that you don't understand the nature of char* and char**. 
char *str = "hello! I am from China and i want to make friends with foreigners"; 
char **ptr = {"hello!","i want to learn spoken English","[email protected]"}; 
//Allocate memory for a char** variable. Two steps as follows: 
int length[3] = {6,31,16}; 
char **ptr2 = new char*[3]; 
for(int i = 0;i < length[i];i++) 
    *(ptr2 + i) = new char [length[i]]; 
//delete according to a reverse order. 
관련 문제