2014-01-17 3 views
2

저는 C++의 초보자로서 언어 학습과 놀기입니다. 내가 이해하지 못하는 행동을하는 코드를 썼다. 누가 아래의 코드가 임의의 정크를 인쇄하고 목록의 첫 번째 문자 (즉, a)를 인쇄하지 않는지 설명 할 수 있습니까? 내가 출력 a에 기대있을 때 왜 함수가 char을 반환해야 할 때 쓰레기를 반환합니까?

#include <iostream> 
#include <vector> 
#include <string> 
#include <cstdlib> 
#include <ctime> 
#include <climits> 
#include <stdio.h> 


char* str2char(std::string str) 
{ 
    char cset[str.size()+1]; // +1 for the null character 
    for(int i = 0; i < str.size(); i++) 
    { 
     cset[i] = str[i]; 
    } 
    cset[str.size()] = '\0'; 
    return cset; 
} 

int main (int argc, char * const argv[]) { 



    std::vector<std::string> ladontakadet; 
    ladontakadet.push_back("aabcbbca"); 
    ladontakadet.push_back("abcdabcd"); 
    ladontakadet.push_back("cbbdcdaa"); 
    ladontakadet.push_back("aadcbdca"); 
    ladontakadet.push_back("cccbaaab"); 
    ladontakadet.push_back("dabccbaa"); 
    ladontakadet.push_back("ccbdcbad"); 
    ladontakadet.push_back("bdcbccad"); 
    ladontakadet.push_back("ddcadccb"); 
    ladontakadet.push_back("baccddaa"); 

    std::string v = ladontakadet.at(0); 
    char *r; 
    r = str2char(v); 
    std::cout << r[0] << std::endl; 
    return 0; 
} 

는 왜이 쓰레기를 반환?

도움이 필요하시면 Thnx!

P. 이 코드의 출력은 임의적입니다. 항상 동일한 문자를 인쇄하지는 않습니다. : S

+3

을, 그것을 만드는입니다 코드 복사가 불가능합니다. –

+0

간단한 형식 코드는 이미지가 과도 함을 나타냅니다. – legends2k

+2

+1 그래, 미안 해요 – jjepsuomi

답변

1

: 코드의 스크린 샷을 게시하지 마십시오 향후

#include <iostream> 
#include <vector> 

void f(char* s) { 
    s[0] = 'H'; 
} 

std::vector<char> to_vector(const std::string& s) { 
    return std::vector<char>(s.c_str(), s.c_str() + s.size() + 1); 
} 

int main(void) 
{ 
    std::string s = "_ello"; 
    std::vector<char> t = to_vector(s); 
    f(t.data()); 
    std::cout << t.data() << std::endl; 
} 
12

함수가 반환 될 때 범위를 벗어나는 로컬 변수 인 로컬 변수에 대한 포인터를 반환하기 때문입니다.

인수에 이미 std::string을 사용하고 있습니다. 배열과 리턴 포인터 대신에 이것을 사용하십시오.

+0

당신의 도움을 Thnx +1 ... 나는 그 대신에 (문자열을 사용하여) 자신을 생각 해왔다. (그러나 내 문제는 내가 다른 사람이 작성한 코드를 사용하고 있는데, t는 가고 싶다. (길기 때문에), char 배열 x를 사용해야한다. ( – jjepsuomi

+3

가변 길이 배열은 처음에는 쓸모가 없다.) – jrok

+3

@jjepsuomi, 언제든지 돌아가서'string을 사용할 수있다. C- 문자열을 검색하려면 c_str()'을 사용하십시오. – Shoe

2

함수가 반환 된 후 범위를 벗어나는 로컬 변수의 주소를 반환하기 때문에 함수가 가비지를 반환합니다. 아마 다음과 같아야합니다

char* str2char(const std::string &str) 
{ 
    char *const cset = new char[str.size() + 1]; // +1 for the null character 
    strcpy(cset, str.c_str()); 
    return cset; 
} 

당신은 당신의 변수 rdelete[] r;을 수행하여 삭제해야합니다. 이상적으로 당신은 원시 포인터를 사용하지 않을 것이고 std::string을 모든 것에 사용하거나 char *std::unique_ptr에 넣을 것입니다. 당신의 목표는 숯불 *의 내용을 수정하는 기능에 성병의 내용 : 문자열 전달하는 경우

+0

+1 도움을 주셔서 감사합니다. @MarkIngram 좀 더 설명해 주시겠습니까? "함수 뒤에 범위를 벗어난 지역 변수의 주소 return "=) 왜 범위를 벗어나는가? :) – jjepsuomi

+1

@jjepsuomi 스택 상에 변수'cset'을 생성한다 (힙과 비교하면된다). 범위의 끝에서,이 경우 함수 (기본적으로'{}'대괄호)는 스택이 팝되고 모든 변수가 파괴되어'cset' 변수가 파괴되었음을 의미합니다. 그런 다음 파괴 된 변수를 반환합니다. 즉, 이제는 가비지를 가리키고 있습니다. –

+0

+1 감사합니다. – jjepsuomi

관련 문제