2013-07-20 4 views
1

char 배열의 배열을 반환하는 중입니다. 배열을 성공적으로 만들 수는 있지만 분명히 잘못 반환하고 있습니다.함수에서 char 포인터 배열 반환 (C++)

내 구문이 해제되어 있습니까? 아니면 내가 간과하고있는 다른 오류가 있습니까? 여기

은 전체 기능이 여기에
// prototype 
    char * testFunc(); 

// Function 
    char * testFunc() { 
     char* ptrArray[2]; 
     return(*ptrArray); 
    } 
// Assignment in main() 
    int main { 
     char * res = testFunc(); 
    } 

는 "이라고도 자동 저장 (에 할당 된 전체 코드 객체를 반환

#include <iostream> 
using std::cout; 

// prototype 
char * testFunc(); 

int main() { 

    short i, j; 
    char * res = testFunc(); 

     for (i=0; i < 2; i++) 
      cout <<"This is res[" << i << "] : " << res[i] <<"\n"; 


    return(0); 
} 

char * testFunc() { 

    char word1[] = "one"; 
    char word2[] = "two"; 

    // create an array of char* 
    char* ptrArray[2]; 

    ptrArray[0] = word1; 
    ptrArray[1] = word2; 

    for (int i=0; i<2; i++) 
     cout <<"This is ptrArray[" << i << "] : " << ptrArray[i] <<"\n"; 

    return(*ptrArray); 
} 
+0

http://stackoverflow.com/questions/3716595/c-returning-multidimension-array-from-function – yuan

답변

4

의 단순화 된 버전에 따라 가장 관련성이 라인이다 스택 개체 ")는 정의되지 않은 동작입니다.

  1. 돌아 정적 저장 영역에 할당 된 객체,
  2. 돌아 동적 저장 영역에 할당 된 객체 또는
  3. 을 가지고 : 당신이 C에서 배열을 반환해야 할 경우, 당신은 세 가지 옵션이 있습니다 버퍼 및 최대 크기를 반환하고 배열의 실제 크기를 반환합니다.

첫 번째 옵션은 함수가 이 아닌이되기 때문에 거의 적용 할 수 없습니다. 세 번째 옵션은 광범위하지만 제한이 있습니다. 버퍼에 맞는 것보다 많은 데이터를 반환해야하는 경우 API를 여러 번 호출해야합니다.

이렇게하면 옵션 번호 2가 남습니다. new을 사용하여 반환 할 메모리를 할당하고 데이터를 복사 한 다음 호출자에게 결과를 반환하십시오.

// You need two asterisks: a string needs one asterisk, you return 
// a 1-D array of strings, so you need another level of indirection. 
char ** testFunc() { 
    char word1[] = "one"; // Automatic memory - needs a copy 
    char word2[] = "two"; // Automatic memory - needs a copy 

    // create an array of char* 
    char** ptrArray = new char*[2]; 

    ptrArray[0] = new char[strlen(word1)+1]; // Plus one for the null terminator 
    strcpy(ptrArray[0], word1); 
    ptrArray[1] = new char[strlen(word2)+1]; // Plus one for the null terminator 
    strcpy(ptrArray[1], word2); 
    for (int i=0; i<2; i++) 
     cout <<"This is ptrArray[" << i << "] : " << ptrArray[i] <<"\n"; 

    return ptrArray; 
} 

참고 : 아직 표준 라이브러리에 도달하지 않았기 때문에 아래 해결 방법이 적용되지 않을 수 있습니다. C++ 11 수에서

vector<strig> testFunc() { 
    vector<string> res; 
    res.push_back("one"); 
    res.push_back("two"); 
    return res; 
} 

을 : 당신이 읽을 훨씬 더 쉽게 코드를이 재치 동적 용기를 다시 작성하고, 할 수 있습니다 : 그러나, 당신은 위의 솔루션은 최고의 C의 ++가 할 수없는는 것을 알아야한다 더 나아질 수 있습니다 :

vector<string> test() { 
    return vector<string> {"one", "two"}; 
} 
+0

감사합니다. 'realloc'의 올바른 사용에 대한 힌트가 있습니까? 나는'char * retArray = (char *) realloc (ptrArray, sizeof (ptrArray));와 같은 행운을 가지고 있지 않다. –

+0

이 답은 함수 return-signature가 정확하지 않다는 사실을 놓치고있다. 포인터가 필요하지만 char 포인터의 배열이되어야합니다! 메모리 스콥에 대한 그의 조언은 도움이된다. –

+0

@RicardoSaporta - C가 malloc의 크기를 추적하지 않습니다. 컬렉션을 동적으로 확장하는 경우 목록 헤더를 통해 크기를 추적해야합니다. STL 컨테이너를 사용하는 것이 가장 좋습니다. http://www.cplusplus.com/reference/list/list/ –

1

하나의 "문자 배열"은 대략 char *과 같습니다. 배열 배열을 반환하려면 char ** 또는 아마도 char[]*이 필요합니다.

다른 답변에서 말하지만, 함수 내부에서 포인터를 반환하는 경우 함수 내에서만 유효한 로컬 변수가 아닌 "전역"메모리 여야합니다. "스택 기반"로컬 변수에 대한 포인터는 함수가 리턴 한 후에 더 이상 유효하지 않습니다. 스택 공간은 다음 함수 호출 (또는 더 빨리)에 의해 덮어 쓰여지기 때문입니다.

[원래의 게시 이후 "const correctness"]에 대해 const char* 및 (아마도) const char**이 바람직하다고 제안되었습니다.

내 C++은 녹슬지 않습니다.하지만 :

const char** testFunc() { 
    const char word1[] = "one"; 
    const char word2[] = "two"; 

    // create an array of char* 
    const char** ptrArray = (const char **) malloc(2 * sizeof(char *)); 
    ptrArray[0] = word1; 
    ptrArray[1] = word2; 

    for (int i=0; i<2; i++) 
     cout <<"This is ptrArray[" << i << "] : " << ptrArray[i] <<"\n"; 

    return ptrArray; 
} 

그리고 주에서

: 원래의 질문이 제기됨에 따라

int main() { 
    short i; 

    // get the array -- will now be our responsibility to free 
    const char** ptrArray = testFunc(); 

    for (i=0; i < 2; i++) { 
     // read single pointer (char*), from our array of pointers (char**) 
     const char* word = ptrArray[i]; 
     cout <<"This is res[" << i << "] : " << word <<"\n"; 
    } 

    // free it. 
    free(ptrArray); 

    return(0); 
} 

는 어레이에 대한 입력은 문자열 상수입니다. 따라서 가변 문자열 배열을 반환하면 가변 문자열 배열을 반환하는 것이 좋습니다. 더를위한 버퍼로 취급하지 - (질문에 미도시) 전체 시스템 프로그래밍 문자열을 구축하더라도

는 다른 대답에 따라, 그것은 가능성이보다 더 그들은 최고의 const char *로 반환 될 것이다 가감.

+0

복사를하지 않고'word1'과'word2'를'ptrArray'에 넣을 수 없습니다 : 문자열 리터럴로 초기화 되더라도 실제로는 스택 객체입니다 왜냐하면 OP는 그것들을 const가 아닌 문자 배열로 선언했기 때문입니다. – dasblinkenlight

+0

복사 할 필요없이 const 포인터를 넣을 수 있습니다. 가장 정확하고 효율적인 솔루션입니다. 이것을 지적 해 주셔서 감사합니다. –