2012-06-15 2 views
2

를 사용하는 동안 내가 여기 무슨 일이 일어나고 있는지 모르는 :분할 오류 포인터

#include<stdio.h> 
int main() 
{ 
    int i, j, *k, x,array[]={5,3,4,1,8,9,2,7,6,0}; 
    int *ptr=array; 

    for(j=1;j<10;j++) { 
     printf("---------iteration %d--------------\n",j); 
     *k=*(ptr+j); // the segmentation error is occurring here at this line 
     printf("key=%d\n",*k); 
     i=j-1; 

     while(i>=0 && *k < *(ptr+i)) { 
      *(ptr+i+1)=*(ptr+i); 
      i--; 
     } 

     *(ptr+i+1) = *k; 
     printf("%d\n",*(ptr+i+1)); 

     for(x=0;x<10;x++) 
      printf("%d,",*(ptr+x)); 

     printf("\n"); 
    } 

    for(i=0;i<10;i++) 
     printf("%d,",*ptr++); 

    printf("\n"); 
} 

를 오류는 for 루프에서 printf 문 직후에 발생하는 때 나는 두 측면에서 *를 제거 그것은 작동하지만 대답은 틀립니다.

*k=*(ptr+j) 

내가 오른쪽을보고로까지하지 않았다 :

이 당신이 말한대로 종류 바로 printf() 후, C.

+6

오신 것을 환영합니다 스택 오버플로. 당신이 그렇게 외쳤다면, 여기에 게시 된 코드에서'void main()'을 사용하지 마십시오. 제발, 제발, 레벨 당 4 칸 (탭 없음)으로 들여 쓰기를하십시오. –

+0

그 점에 대해 사과드립니다. 나에게 기사를 보내 주시겠습니까? 아니면 코드를 작성하는 동안 서식 지정 규칙을 말해 주시겠습니까? – hunterr986

+0

또한 __ (2 점 아래)와 '_in'및 '_t'로 끝나는 변수 및 구조와 함수 이름을 몇 가지 발견했습니다! 나에게 설명해 주시겠습니까? – hunterr986

답변

5

문제가에서 포인터를 사용하여 삽입입니다 . 왼쪽에는 분명히 문제가 있습니다. 포인터가 초기화되지 않았으므로 해당 주소에 쓰면 거의 문제가 발생합니다.

오른쪽에는 메모리 액세스 권한이 있지만, 검사를 마치면 괜찮아 보입니다.

+1

'* k'의 요점은 ...'k'만으로도 충분할까? (간접 또는 "역 참조"에 대한 모든 액세스 또는 올바른 용어는 ^^) –

+0

* k는 포인터의 rvalue이며 k 만 사용하면 포인터의 rvalue (ptr + j)가 포인터에 배치됩니다 그러나 주소는 아닙니다. – hunterr986

2

k을 포인터로 선언했지만 가리킬 메모리를 지정하지 않았으므로 쓰기를 수행 할 때 어떤 일이 발생하는지 알 수 없습니다. 쓰기 위해 쓸 메모리를 k = malloc(sizeof array)으로 지정하십시오.

+0

하지만 초기화해야하는 이유는 무엇입니까? 정수 및 문자 등의 가비지 값을 가질 수 있습니까? 내가하고있는 일은 변수 안에있는 기존 값에 할당하는 것뿐입니다. – hunterr986

+0

@ hunterr986 : 포인터가 초기화되지 않은 경우 일반적으로 유효한 메모리 위치가 아닌 준 임의 메모리 위치에 액세스하므로 세그멘테이션 오류가 발생합니다. 또는 널 포인터 일 수 있습니다. 너무 유효하지 않으며 일반적으로 세분화 오류가 발생합니다. 포인터가 유효하다는 것을 모르는 경우, 그것을 사용하는 것이 안전하지 않습니다! ** 그리고 ** 아니요, 당신은 포인터에 할당하지 않습니다; 당신은 (초기화되지 않은) 포인터가 가리키는 것에 할당하고 있습니다. 포인터를 할당하려면 :'k = ptr + j;'는'ptr'와'j'가 제어하에 있다고 가정 할 때 유효한 포인터를줍니다. –

+1

@ hunterr986 당신은 할당 전에 thing-you-are-assigning-to가 쓰레기 값을 가질 수 있다는 점에서 부분적으로 정확 합니다만, 여기있는 것에 대한 할당은'* k'이고' k '는 쓰레기 값을 가지므로'* k'는 유용하게 저장할 수있는 장소가 아니라 의미가 없거나 무효 한 개념입니다. – mlp

1

다른 언급 한 바와 같이, 문제의 일부는 값을 저장하기 위해 단위화된 포인터를 사용하고 있다는 것입니다. 코드를 읽은 후에는 단순히 정수 값을 저장하기 위해 * k를 사용하고있는 것으로 보입니다. 그러므로 당신은 포인터를 할 필요가 없습니다 및 일반 int 값을 사용하면 충분합니다 :

int i, j, k, x,array[]={5,3,4,1,8,9,2,7,6,0}; 
int *ptr=array; 

for(j=1;j<10;j++) { 
    printf("---------iteration %d--------------\n",j); 
    k=*(ptr+j); // the segmentation error is occurring here at this line 
    printf("key=%d\n",k); 
    i=j-1; 

    while(i>=0 && k < *(ptr+i)) { 
     *(ptr+i+1)=*(ptr+i); 
     i--; 
    } 

    *(ptr+i+1) = k; 
} 

또한, * PTR (+ i)는 PTR [I], 일반적인 C/C와 같은 일을 나타낸다 ++ 관례는 최신 양식을 사용하는 것입니다.

+0

나는 주로 포인터를 사용하여 프로그래밍하고 있으므로 포인터를 배우려고합니다. – hunterr986

+0

그런 다음 메모리 위치에 액세스하기 전에 포인터를 초기화하는 방법을 배워야합니다. [code] int * k, km; k = &km; [/ code] km를 사용하면 int에 대한 메모리를 스택에 예약 한 다음 k가이 예약 된 메모리의 주소를 가리 키도록 만듭니다. 이것으로 어떤 손상 문제없이 * k를 사용할 수 있습니다. – SylvainL

0

아래의 코드는 버그가 수정 된 원본과 비슷하지만, 좋은 측정을 위해 몇 가지 조정할 수 있습니다. 주요 수정 (이미 말한 @pst 및 @SylvainL 거의이다.) key*k를 대체

이유를, 알고리즘의 관점에서 것은, 당신이 잠시 이동되는 값을 보유하는 array 이외의 장소가 필요할 것입니다 다른 array 요소가 이동됩니다. 그렇지 않으면 결국 array 요소를 덮어 쓰게되고, "..."에서 판단한 것으로 보이며, 양쪽에서 *을 제거하면 작동하지만 대답이 잘못되었습니다. "덧글.

Wikipedia entry on insertion sort 멋지게 점을 설명하는 좋은 애니메이션이 있습니다
enter image description here (Swfung8 CC BY-SA License page에 의한 이미지)

그들은 단지 도움이 포인터는 질문에 관련이없는 같은 다른 비틀기에 대한

참조 코드 주석, 당신이 떠날 수있는 ;-)

#include<stdio.h> 

int main() 
{ 
    int array[]={5,3,4,1,8,9,2,7,6,0}; 

    int elm, key, i; 
    int *ptr=array; 

    // Calculate the number of array elements so the code will still 
    // work if the data set changes. A good habit, rather than a necessity 
    // in this code, but it is used in two places... ;-) . 

    int array_len = sizeof(array)/sizeof(int); 

    for(elm=1; elm < array_len; elm++) { 
     printf("---------iteration %d--------------\n",elm); 
     key=(ptr+elm); 
     printf("key=%d\n", key); 

     // The while loop here was a for loop in disgise. 

     for (i=elm-1; i >= 0 && key < *(ptr+i); i--) { 
      *(ptr+i+1) = *(ptr+i); 
     } 

     *(ptr+i+1) = key; 
     printf("%d\n",*(ptr+i+1)); 

     // x declaration moved to here as it is only used as a loop counter 

     for(int x=0; x < array_len; x++) 
      printf("%d,",*(ptr+x)); 

     printf("\n"); 
    } 

    for(i=0; i < 10; i++) 
     printf("%d,",*ptr++); 

    printf("\n"); 
}