문제

나는 문자열을 수신하고 일부 구문 분석 후 문자열 배열을 반환하는 간단한 함수를 원합니다. 그래서 이것은 내 기능 서명입니다.

int parse(const char *foo, char **sep_foo, int *sep_foo_qty) {
    int i;
    char *token;
    ...
    strcpy(sep_foo[i], token); /* sf here */
    ...
}

그런 다음 이것을 다음과 같이 부릅니다.

char sep_foo[MAX_QTY][MAX_STRING_LENGTH];
char foo[MAX_STRING_LENGTH];
int sep_foo_qty, error;

...

error = parse(foo, sep_foo, &sep_foo_qyt);

...

이렇게하면 편집 중에 경고를받습니다.

warning: passing argument 2 of 'parse' from incompatible pointer type

그런 다음 여기에 / * sf로 표시된 라인에서 실행 중에 분할 오류 * /

내 C 코드에서 무엇이 잘못 되었습니까?

미리 감사드립니다

도움이 되었습니까?

해결책

경고가 정확히 옳습니다. 당신의 기능은 많은 포인터를 원합니다. 배열 배열을 제공합니다.

예상되는:

 sep_foo:
 +------+       +-----+
 |char**|--> 0: |char*|-->"string1"
 +------+       +-----+
             1: |char*|-->"string2"
                +-----+
*sep_foo_qty-1: |...  |
                +-----+

당신이 제공 한 것 :

           sep_foo:
           +--------------------------------+
        0: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
        1: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
MAX_QTY-1: | ...                            |
           +--------------------------------+

유형 요소가있는 배열 X 포인터로 "부패"할 수 있습니다.X, 또는 X*. 그러나의 가치 X 해당 변환에서 변경할 수 없습니다. 뿐 하나 붕괴 작업이 허용됩니다. 두 번 발생해야합니다. 당신의 경우, X 배열입니다.MAX_STRING_LENGTH-차기. 기능이 원합니다 X 포인터 투-숯이되기 위해. 그것들은 동일하지 않기 때문에 컴파일러는 당신에게 경고합니다. 컴파일러가 허용 한 일에서 좋은 일이 없기 때문에 경고가 약간 놀랐습니다.

기능 에서이 코드를 작성할 수 있습니다.

char* y = NULL;
*sep_foo = y;

그 이후로 법률 코드입니다 sep_foo a char**, 그래서 *sep_foo a char*, 그리고 그렇습니다 y; 당신은 그들을 할당 할 수 있습니다. 하지만 당신이하려고했던 일과 함께 *sep_foo 그렇지 않을 것입니다 진짜 a char*; 그것은 숯불 배열을 가리키고있을 것입니다. 사실상 코드는 다음을 시도합니다.

char destination[MAX_STRING_LENGTH];
char* y = NULL;
destination = y;

포인터를 배열에 할당 할 수 없으므로 컴파일러는 호출이 좋지 않다고 경고합니다.

이것을 해결하는 두 가지 방법이 있습니다.

  • 선언하고 할당하는 방식을 변경하십시오 sep_foo 호출 측면에서 함수가받을 것으로 예상되는 내용과 일치합니다.

    char** sep_foo = calloc(MAX_QTY, sizeof(char*));
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    

    또는 동등하게

    char* sep_foo[MAX_QTY];
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    
  • 기능의 프로토 타입을 변경하여 실제로주는 것을 받아들이십시오.

    int parse(const char *foo, char sep_foo[MAX_QTY][MAX_STRING_LENGTH], int *sep_foo_qty);
    

다른 팁

매개 변수 2가되어야합니다

char sep_foo[][MAX_STRING_LENGTH]

명확히하기 위해, 당신은 parse ()에 포인터를 전달하고 그것을 포인터에 대한 포인터로 취급합니다. C의 다차원 배열은 많은 포인터가 아닙니다. 배열 변수가 가리키는 단일 메모리 블록입니다. 당신은 그것을 두 번의 회의를 할 수 없습니다.

sep_foo 배열 배열로 정의됩니다. 다시 말해, 당신이 사용할 때 sep_foo, 그것은 순차적 메모리의 시작을 가리 킵니다. 다음은 모델입니다.

(assume MAX_STRING_LENGTH = 16, MAX_QTY = 2)
sep_foo       = &&0000
sep_foo[0]    =  &0000
sep_foo[0][0] = *&0000 = 12
sep_foo[0][8] = *&0008 = 74
sep_foo[1]    =  &0010
sep_foo[1][0] = *&0010 = 12


0000  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE
0010  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE

그러나 기능은 다양한 포인터 (실제로 포인터에 대한 포인터)를 기대합니다. 이것은 다음과 같이 모델링됩니다.

sep_foo_arg       =   &&0000
sep_foo_arg[0]    =  *&&0000 = &0010
sep_foo_arg[0][0] =  *&*&0000 = 12
sep_foo_arg[0][8] = *(&*&0000 + 8) = 74
sep_foo_arg[1]    =  *&&0002 = &0020
sep_foo_arg[1][0] = *&*&0000 = 12

0000  0010 0020  xxxx xxxx  xxxx xxxx  xxxx xxxx

0010  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE
0020  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE

그래 ... 구문은 내 설명에 약간 혼란 스러울 수 있습니다 ...

어쨌든, 당신은 당신의 기능에 포인터를 취급하는 방법을 말 함으로써이 문제를 해결할 수 있습니다. 특히, 배열 (메모리 시퀀스)으로 취급하려고합니다.

int parse(const char *foo, char (*sep_foo)[MAX_STRING_LENGTH], int *sep_foo_qty);

그것이 당신의 정확한 코드라면, 나는 segfault가 당신이 메모리를 char* token 구문 분석 기능 내부에서 Strcpy에서 사용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top