2013-02-23 5 views
-1

문자열 벡터 배열을 반환하는 데 문제가 있습니다. 나는 기능이 있습니다C++에서 벡터 배열 반환

std::vector<std::string>* generatecVec(std::vector<std::string> strVec){ 
    std::vector<std::string> cVec[3]; 
    cVec[0].push_back("Test11"); 
    cVec[0].push_back("Test12"); 
    cVec[0].push_back("Test13"); 
    cVec[1].push_back("Test21"); 
    cVec[1].push_back("Test22"); 
    cVec[1].push_back("Test23"); 
    cVec[2].push_back("Test31"); 
    cVec[2].push_back("Test32"); 
    cVec[2].push_back("Test33"); 
    return cVec; 
} 

을 나중에 나는

std::vector<std::string> *cVec = generatecVec(strVec); 
for(std::vector<string>::iterator it = cVec[0].begin(); it != cVec[0].end(); ++it) { 
    std::cout << *it; 
} 

같은 기능을 사용하지만 세그먼트 오류가 계속. 포인터를 부적절하게 사용해야한다는 것을 알지만 어떻게 해결할 수 있습니까? 인덱스로 참조하기가 쉽기 때문에 벡터 배열을 사용합니다 (동적 인 경우는 3 개만 필요함). 감사!

+0

'strVec '이란 무엇입니까? – kay

+1

질문에 대한 답변을 수락하지 않은 것을 확인했습니다. [수락 및/또는 upvote] (http://meta.stackexchange.com/a/168143/206447) 도움이되는 답변. – Dukeling

답변

4

함수의 범위에만있는 포인터를 반환하고 있습니다. 기능이 완료되면 cVec이 사라지고 발신자에게 매달린 포인터가 남아 있습니다. std::array<std::vector<std::string> 3>과 같이 실제로 복사 할 수있는 객체를 반환하는 것이 좋습니다. 이 기능에 어떤 역할을하지 것 때문에

#include <array> // for std::array 

std::array<std::vector<std::string>,3> generatecVec(/*std::vector<std::string> strVec*/){ 
    std::array<std::vector<std::string>,3> cVec; 
    cVec[0].push_back("Test11"); 
    cVec[0].push_back("Test12"); 
    cVec[0].push_back("Test13"); 
    cVec[1].push_back("Test21"); 
    cVec[1].push_back("Test22"); 
    cVec[1].push_back("Test23"); 
    cVec[2].push_back("Test31"); 
    cVec[2].push_back("Test32"); 
    cVec[2].push_back("Test33"); 
    return cVec; 
} 

여기 strvec을 주석했다.

그런 다음이 (루프 구문을 기반으로 C++ 11 범위)처럼 사용할 수 있습니다

auto cVec = generatecVec(); // no strVec because it doesn't play any role 
for(auto it = cVec[0].cbegin(); it != cVec[0].cend(); ++it) { 
    std::cout << *it; 
} 

참고 컴파일러는 C++ 11 초기화 목록 초기화를 지원하는 경우 push_backs이 필요하지 않을 수있다.

컴파일러가 std::array을 지원하지 않는 경우 std::tr1::array 또는 boost::array을 시도하십시오.

0

범위를 벗어나 포인터가 파괴 된 벡터로 가득 찬 파괴 된 배열을 가리키면 파괴되는 자동 배열에 대한 포인터를 반환합니다.

사용 std::array과 가치에 의해 반환 :

// This means: std::array of 3 std::vector<string> 
// Type--VVVVVVVVVVVVVVVVVVVVVVVV V-- Array size 
std::array<std::vector<std::string>, 3> generatecVec(std::vector<std::string> strVec){ 
    return { { 
    { "Test11", "Test12", "Test13" }, 
    { "Test21", "Test22", "Test23" }, 
    { "Test31", "Test32", "Test33" } 
    } }; 
} 

auto cVec = generatecVec(strVec); 
for(auto it = cVec[0].begin(); it != cVec[0].end(); ++it) { 
    std::cout << *it; 
} 
0

그것은 당신이 벡터의 수집을 필요로 할 때 당신은 문자열의 수집,하지만 포인터를 필요로 할 때 당신은 문자열의 벡터를 사용하는 것이 이상하다. 형식 정의는 세부 사항의 추상화에 도움이 가능한 솔루션을 볼 수 사용 : 다른 사람이 이미 설명

typedef std::vector<std::string> strings; 
typedef std::vector<strings> strings_seq; 

strings_seq generateVec() 
{ 
    strings_seq cVec(3); 
    cVec[0].push_back("Test11"); 
    cVec[0].push_back("Test12"); 
    cVec[0].push_back("Test13"); 
    cVec[1].push_back("Test21"); 
    cVec[1].push_back("Test22"); 
    cVec[1].push_back("Test23"); 
    cVec[2].push_back("Test31"); 
    cVec[2].push_back("Test32"); 
    cVec[2].push_back("Test33"); 
    return cVec; 
} 
0

으로 로컬 참조를 반환하는, 그 기능 범위 이외의 쓰레기입니다. 어림짐작으로, 가능한 한 원시 포인터를 피하려고합니다. 사용 후 포인터를 삭제하거나 포인터를 처음부터 초기화하는 것을 잊어 버리기 때문입니다.

std :: array 또는 std :: vector를 반환하면 복사 생성자를 호출하고 벡터, 배열 등의 새로운 복사본을받습니다. 개인적으로 이러한 상황에 대해 shared_ptr을 사용하는 경향이 있습니다. 고전적인 C 포인터와 함께 오는 단점을 극복하십시오.

+0

'std :: array' 또는 다른 것을 값으로 반환하면 ** 의미 론적으로 ** 복사하지만, C++ 표준에서는 여기에서 복사 제거, 특히 반환 값 최적화 (RVO)가 허용되며 대부분의 현재 컴파일러는 . 그래서 실제로'shared_ptr'를 돌려주는 것에는 거의 요지가 없습니다. 스마트 포인터를 반환했다면이 경우에는 'unique_ptr'이어야합니다. – juanchopanza

+0

일 수 있습니다.모든 컴파일러가 이러한 최적화를 사용한다고 보장 할 수는 없습니다. 그래서 깨끗한 코드 (shared_ptr 또는 unique_ptr)를 작성하는 것이 목표 환경이 그러한 최적화를 원한다는 것보다 낫다 –

+0

깨끗한 코드가 값에 의해 반환되고 있다고 말할 수있다. 컴파일러가 RVO를 수행하지 않을 가능성이 더 높기 때문에 인수를 거꾸로 뒤집을 것입니다. * RVO를 수행하지 않는 컴파일러를 사용하면 대안을 생각할 수 있습니다. 한 가지 대안은 더 현대적인 컴파일러를 얻는 것입니다! – juanchopanza