2013-12-08 2 views
2

다음 코드의 결과는 실행 때와 이유를 알아낼 수 없습니다 :분할 오류가 세그먼트 오류에

0 0x00007ffff7b95d9b in std::string::assign(char const*, unsigned long)() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6; 
1 0x0000000000400867 in main() 
+1

한 질문 : 사용하는 이유는 무엇입니까 동적 할당은 여기에 있습니까? 당신이 그것에 대한 좋은 대답이 없다면, 당신은 그것을 사용해서는 안됩니다. – juanchopanza

답변

8

malloc을 C++ 코드에서 사용하지 마십시오. 거의 올바른 선택이 아닙니다.

옵션은 다음과 같습니다

Token tok; 
tok.val = "myval"; 

auto tok = std::make_unique<Token>(); // C++14 
tok->val = "myval"; 

auto tok = std::unique_ptr<Token>(new Token()); // C++11 
tok->val = "myval"; 

auto tok = std::make_shared<Token>(); // C++11, use if resource is shared 
tok->val = "myval"; 

Token* tok = new Token(); 
tok->val = "myval"; 
delete tok; 

이 옵션은 대부분의 경우 충분합니다.

위에서 아래로 옵션을 선호하십시오 : 기본 방법은 객체를 만들고 나서 unique_ptr, shared_ptr 그리고 절대적으로 필요한 경우에만 원시 포인터를 처리해야합니다.

이유는 쉽습니다 : 예외 안전 및 메모리 누수. 객체는 유출 될 수 없으며 deleteunique_ptr 또는 shared_ptr으로 잊어 버릴 수는 있지만 원시 포인터로 수행 할 수 있습니다. 또한 원시 포인터는 예외가 발생해도 삭제되지 않습니다. shared_ptr에 오버 헤드 (스레드 카운터를 안전하게 유지하기위한 원자 카운터)가 있으므로 unique_ptrshared_ptr으로 설정해야합니다. 모든 (C++ 14 make_unique없이) 잘 컴파일합니다

데모 : Demo

6

:

#include <cstdlib> 
#include <string> 
#include <iostream> 


using namespace std; 

struct Token 
{ 
    int num; 
    string val; 
}; 


int main() 
{ 
    Token* tok = (Token*) malloc (sizeof(Token)); 
    tok -> val = "myval"; 
    std::cout<<tok->val; 
} 

는 역 추적을 볼 malloc은 생성자를 호출하지 않습니다. new을 사용해보세요. 정상적으로 작동합니다.

나중에 delete을 잊어 버리거나 스마트 포인터를 사용하거나 직접 변수를 스택에 저장하십시오.

+2

그리고 메모리를 해제하기위한'delete' – P0W

+2

또는 객체를 자동으로 인스턴스화하십시오. – juanchopanza

4

Here's why you cannot use malloc with std::string :

당신은 C에 적지 않은 생성자 클래스를 malloc을 할 수없는 ++. 당신이 get malloc에서 제대로 구성된 개체 포함되지 않은 원시 메모리 블록입니다. 해당 메모리를 "실제"개체로 사용하려는 시도는 실패합니다.

뿐만 아니라 (이미 다른 답변에서 지적) :

문제는 예제의 생성자를 호출하지 않는 malloc에 ​​있습니다. 문자열은 일반적으로 스택에 포인터로 표시되기 때문에이 은 0으로 설정되고 널 포인터를 역 참조하게됩니다. 대신 을 사용해야합니다.

당신은 당신이 새로운 위치 (자세한 내용은 링크를 참조)를 사용하거나 일반 팔자 'const char* 사용할 수 있습니다 중 하나의 malloc을 사용하여 주장하는 경우 :

struct Token 
{ 
    int num; 
    const char* val; 
}; 

int main() 
{ 
    Token* tok = (Token*) malloc (sizeof(Token)); 
    tok->val = "myval"; 
    std::cout << tok->val; 
    free(tok); 
} // will not seg fault 
+1

'char *'를 사용하는 것은이 경우에있어서 정말 나쁜 생각입니다. 그런 다음 수동으로 메모리를 관리해야합니다. –

+0

@ 이반 당신은 정교 할 수 있습니까? –

+0

'char *'는 단지 포인터 일뿐입니다. 여전히 포인터가 가리킬 메모리를 할당 한 다음 적절하게 할당을 해제해야합니다. 'Token * tok; '라고 쓰면 완전히 기능적인 객체라고 기대할 수 없다는 것과 같은 이유 때문입니다. –