2016-07-23 1 views
0

나는 프로젝트 작업을하고 있으며, 지난 1 시간 동안 코드에서 버그를 찾으려고 노력했다. 더 면밀히 조사한 후에, 나는 문제가되어 버린 다소 이상한 것을 발견했습니다.초기 배열 요소의 주소가 같은지 비교하는 이유는 무엇입니까?

내 배열의 초기 요소 주소는 이상하게도 과 동일하게 비교됩니다. 내 코드를 구분하고 테스트 코드를 시도했는데 비슷한 결과가 나타납니다. 누군가이 이상한 행동을 설명 할 수 있습니까?

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    char buf[256]; 

    char *p1 = buf; 
    char *p2 = buf + 3; 

    if (memcmp(p1, p2, sizeof(char *)) == 0) { 
     puts("equal..."); 
    } 

    p1 = buf + 100; 
    p2 = p1 + 3; 

    if (memcmp(p1, p2, sizeof(char *)) == 0) { 
     puts("equal..."); 
    } 
    return 0; 
} 
+1

'memcmp는 (P1, P2를 원하는 ... '됩니다 * * 포인터의 주소를 비교하지. 그것은 하나, 그 값을 비교하지 않습니다. 그것이 무엇을하는 수를 비교하는 것입니다 'p1, p2 '에 의해 보관 유지되고있는 주소로 시작되는'sizeof (char *)'와 같은 아르바이트의 바이트 수. 거기에 아무것도 저장되어 있지 않기 때문에, 비교 결과는 미정 도리입니다. * undefined *의 많은 결과 중의 하나는, – dxiv

답변

2

당신은 정의되지 않은 동작 있습니다.

로컬 변수는 단순한 정수 또는 배열과 상관없이 초기화되지 않습니다. 값은 이며, 불확도는입니다. 어떤 식 으로든 그것들을 사용하면 심지어 초기화를하기 전에 의 정의되지 않은 동작으로 연결됩니다.

또한 두 문자를 비교하지 않고 32 비트 또는 64 비트 시스템에 있는지에 따라 한 번에 4 개 또는 8 개의 문자를 비교합니다. 단일 문자를 비교하려면 sizeof(char) (항상 1과 같도록 지정해야 함)을 사용해야합니다. 포인터를 비교하는 것도 아니며, 포인터가 가리키는 것을 비교하는 것입니다.

두 개의 단일 문자를 비교하려면 예를 들어, 같은 등호 비교 연산자 ==을 사용하십시오. *p1 == *p2 또는 보통 buf[0] == buf[3].

+1

단일 문자를 비교하고 싶다면 아마 배열 색인 또는 참조 해제를 사용하고 우선적으로 memcmp를 사용하는 대신에 평등을 비교하는 것이 가장 좋습니다. – Taywee

+1

이제 알았습니다. 가지고있다. ritten :'memcmp (& p1, & p2, sizeof (char *)) == 0)'맞습니까? –

+0

@layzak 절대적으로 아닙니다. 그들의 내용이나 주소 자체를 비교하려고합니까? 내용을 비교하려면,'sizeof (char *)'를 실제 버퍼 크기로 바꾸고 싶을 것이다. 주소를 비교하기 위해서는 단지'py == p2'입니다. 포인터는 다른 포인터와 쉽게 비교할 수 있습니다. – Taywee

1

memcmp 주소를 비교하지 않습니다. 메모리를 비교합니다.

int memcmp(const void *s1, const void *s2, size_t n); 

memcmp은 동일한 있다면 볼 s1s2의 첫 번째 n 바이트를 비교합니다. 여기

, 당신은

if (memcmp(p1, p2, sizeof(char *)) == 0) { 

sizeof(char *)

이 아키텍처에 따라, 될 가능성이 4 또는 8 포인터의 크기를 가고 있습니다.

즉, 첫 번째 sizeof(char *) 바이트의 p1과 p2가 동일한 지 비교하려고합니다. 이 데이터를 초기화하지 않으므로 아무 일도 일어나지 않을 것입니다. 나는 실제 코드가 0이라고 가정하고 있는데, 이는 왜 항상 같은지 비교하는 이유를 쉽게 설명 할 것입니다.

0

디버거에서 코드를 실행하고 buf의 내용을 확인하십시오. 일부 컴파일러는 배열의 모든 항목을 디버그 모드로 제로화하고 릴리스 빌드에서 불확정 값을 제공합니다. 또는 릴리스 빌드에서 코드를 실행하고 그들은 여전히 ​​내가 memcmp() 생각

0

동일한 경우 확인 메모리 하지에 당신이 통과 포인터를 컨텐츠 현재를 비교합니다.당신은 귀하의 질문에 당신의 4 바이트의 내용을 비교하기 위해 노력하고

/* to compare addresses */ 
/* simple one */ 
if(p1 == p2) 

/* redundant one */ 
if(!memcmp(&p1, &p2, sizeof(p1)) 
+0

@dxiv 오, 죄송합니다. 감사합니다. –

0

을 위해는 sizeof (1)

따라서 수정 된 코드로 포인터와 크기로 포인터 (주소)를 통과 포인터를 비교하려면 포인터 변수는 p1p2입니다. 그러나 실제로는 p1p2이 가리키는 4 바이트를 비교하고 있습니다. 그 이유는 이것이 memcmp입니다.

memcmp의 처음 두 인수는보고자하는 데이터의 메모리 주소이며, 변수의 메모리 주소는 변수 앞에 & 연산자를 사용하여 나타냅니다.

당신은,

memcmp(&p1, &p2, sizeof(char*)); 
+0

'memcmp (& p1, & p2, sizeof (char *)); 또는 간단히 원합니다. 더 읽기 쉽고, 단지'p1! = p2;'이다. – dxiv

관련 문제