2017-01-05 6 views
0

내 Mac 노트북에는 4GB 1600MHz DDR3 메모리가 있습니다. 고전 MemoryBlock 클래스에서 Memoryblock 클래스는 오버플로 후에 숫자와 이유 및 방법을 제공합니다.

class MemoryBlock 
{ 
public: 
    // Default constructor 
    explicit MemoryBlock(): _length{0}, _data{nullptr} {} 
    explicit MemoryBlock(const int l): _length{l}, _data{new int[l]} {} 

    // Big-Five (blahblah) 
    // -------- 

    int length() const 
    { 
     return _length; 
    } 

private: 
    int _length; 
    int* _data; 
}; 

은 그 때 나는 1e111e101e9에서 x을 변경, 같은 오버 플로우 뭔가 후 어떤 일이 발생하는지 알아보기 위해 노력했다. 이 날을 제공

MemoryBlock x(100000000000); 
Info<< "x's length = " << x.length() << endl; 

warning: overflow in implicit constant conversion [-Woverflow] 
    MemoryBlock x(100000000000); 

size_t_length 같은 형식을 사용하여, 나는 할 수 없습니다,

[LOG] x( 1000000000)'s length = 1000000000 
[LOG] x( 10000000000)'s length = 1410065408 
[LOG] x(100000000000)'s length = 1215752192 

경고 뭔가처럼, (g++-6cmake 컴파일) 왜 그런지 알지 못하고이 경고를 보게됩니다.

어쨌든 제 질문은 어떻게 14100654081215752192이 생성됩니까? 감사

답변

3

12157521922^32가 (대부분의 플랫폼 int의 크기) 32 비트 정수 의 최대 값을 표현할 수있다 100000000000 % 2^32의 결과이다. signed overflow is undefined behavior! 행동이 그래서 당신의 100000000000가 오버 플로우하지 않습니다, (이 implementation defined의로, 특정 플랫폼) 및

  • 서명되지 않은 64 비트 로 표현할 수있는 범위를 증가 : std::size_t를 사용

    중 하나 보인다 ...

  • 정의 ... 또는 100000000000는 (그러나 잘 정의 된 방식으로) 오버플로 부호없는 32 비트까지 표현 가능한 범위를 증가한다.

제 1 항 내지 제 4 항 중 확신 할 수있는 유일한 방법은 sizeof(int)sizeof(std::size_t)이 컴퓨터에로 평가 무엇인지 확인하고 코드에서 발생하는 정확한 오버 플로우를 파악하는 것입니다.

특정 정수에 특정 비트가 있음을 보장하려면 "Fixed width integer types"을 조사해야합니다.


cppreference/Fundamental types에는 C++의 기본 유형에 가장 일반적인 범위가 포함 된 멋진 테이블이 있습니다.

-fsanitize=undefined을 사용하여 유사한 서명 된 오버 플로우 문제를 포착 할 수도 있습니다.

+0

@ NathanOliver : 나는 매우 열악한 말을 남겼다. 바라건대 지금은 덜 오해의 소지가 있습니다. –

+0

@ NathanOliver : 예, OP의 아키텍처에 대한 세부 정보를 알지 못해도 매우 까다로운 일입니다. 나는 그 해답을 더 발전 시키려고 노력할 것이다. –