2011-08-15 7 views
1

정수 배열은 여기에 정렬되어 있지만 문제가 있습니다 : 프로그램을 실행할 때마다 때때로 "변수 '숫자'의 스택이 손상되었습니다"라는 메시지가 나타나고 때로는 숫자 8을 반복해서 인쇄합니다. 여기 있습니다 (2010 Visual C++에서 컴파일) 내 코드 :이 코드가 내 배열을 인쇄하지 않는 이유는 무엇입니까?

즉시 나를 밖으로 점프
#include <iostream> 
#include <cstdlib> 
using std::cout; 
using std::endl; 

void swap(int *x, int *y) 
{ 
    int tmp=0; 
    tmp = *x; 
    *x = *y; 
    *y = tmp; 
    tmp = 0; 
} 

int main() 
{ 
    int numbers[13] = {8,16,23,487,2,301,48,0,13,10,644,12}; 

    int size = sizeof(numbers)/sizeof(int); 

    //sort 

    int i = 0; 
    int* a = &numbers[0]; 
    int* b = &numbers[1]; 


    while(i < size){ 

     if(*a > *b){ 
      swap(a, b); 
     } 

     *a++; 
     *b++; 
     i++; 
    } 

    //Print our results 
    int loopIterator = 0; 
    int numToPrint = 0; 
    while(loopIterator < size){ 
     cout << numbers[numToPrint] << endl; 
     loopIterator++; 
    } 


    system("PAUSE"); 

} 
+7

을 주님 께서 말씀 : 여기에 STL을 사용하여 원하는 결과를 달성하기 위해 하나의 방법하여야한다 정수는 항상 4 ... * 한숨 *를 사용는 sizeof (int)를. –

+1

'int size = sizeof (numbers)/sizeof (int);' – KevinDTimm

+4

위의 해결 방법 모두 차선책입니다. 더 나은 :'size_t size = sizeof numbers/sizeof numbers [0];' –

답변

2

먼저, numToPrint을 증가시키지 않으므로 numbers[0] 이상의 값을 인쇄하지 않습니다. 당신의 while 루프 테스트 i < size을 사용하기 때문에, 당신은 당신의 b 포인터 numbers의 외부 메모리를 액세스하는 것, 루프의 마지막 반복에 있으며,

while(loopIterator < size){ 
    cout << numbers[numToPrint++] << endl; 
    loopIterator++; 
} 

둘째 : 최소한으로 코드를 변경 , 그리고 그 값을 numbers (즉, a가 가리키는 곳)의 마지막 슬롯으로 교환 할 수도 있습니다. 이 시나리오를 피하려면 테스트를 i < (size - 1)으로 변경하십시오. i == 0의 경우 예를 들어, 당신은 a = &numbers[0]b = &numbers[1]이 다음 i == 12, 당신은 a = &numbers[12]b = &numbers[13]와 끝까지가는 그 시간에 ... b이 인스턴스를 가리키고 있는지 값이 배열의 끝을지나이다. 컴파일러가 스택을 설정하는 방법과 스택에 numbers을 할당 한 방법에 따라 bmain() 함수의 활성화 레코드 데이터 구조를 가리키면 실제로 프로그램에 약간의 혼란을 불러올 수 있습니다. 동시에 그것을 부패시킨다.

+2

두 개의 인덱스가있는 이유는 무엇입니까? 카운팅 루프를 원하면 카운팅 루프를 사용해야합니다. (int i (0); i AJG85

+1

잘 작동합니다 ... 나는 단지 코드에서 에러를 지적하고 있었고 빠른 수정 방법은 문자를 두 개 더 추가하는 것뿐입니다. – Jason

0

잘 한 점은 시간의 [0], 크기 번호 번호를 인쇄 할 수 있도록 결코 numToPrint를 증가되지 않는 것입니다.

본인은 위의 같은 일을하는 청소기 방법입니다 당신이, 코드의 인쇄 결과 섹션을 제거 얻을 수와

for (int i = 0; i < size; i++) 
    cout << numbers[i] << endl; 

에 인쇄 부분을 재 작성합니다.

당신이 만지면 안되는 메모리 부분에 쓰고 있기 때문에 아마도 나타나는 오류 메시지입니다. 이는 아마도 "sizeof"를 잘못 사용 한 결과 일 수 있습니다. 메모리 크기가 아닌 숫자로 요소 수를 반환합니다. 두 번째 문제에 대한 올바른 해결책에 대한 실제 질문에 대한 의견을 확인하는 것이 좋습니다.

+0

이것은 OP가보고 한 두 가지 오류 중 하나임을 유의하십시오.) – KevinDTimm

+0

Heh, yea, 내가 확실히 보았던 한 가지를 언급하고있었습니다. yi_H로가는 sizeof의 잘못된 사용법에 대한 해결책으로 두 가지 모두에 답변하도록 편집되었습니다. –

0

한 번만 번호의 목록을 통해 실행으로

+0

'sizeof numbers '는 요소가 아닌 바이트 단위로 측정 된 크기입니다. 요소의 크기로 나누면 정확합니다. (예 :'sizeof numbers [0]') –

+0

@Ben - downvote 앞에 고정되어 있습니다. OP – KevinDTimm

+0

에 대한 의견을 참고하십시오. 너무 느려서 downvote를 벗지 못했습니다. 당신의 대답은 여전히 ​​실제로 질문에 대답하지 않습니다. –

0
(버블 정렬의 절반 구현의 그것의 종류)이 인접 항목을 교환하지만이 목록을 정렬하지 않도록 이런 종류가 작동하지 않습니다

난 당신이 여기 연산자 우선 순위 문제가 확실 해요 :

*b++; 

사실은, 컴파일러는 더 부작용합니다 (*)와 운영자에 대해 경고해야합니다.

게다가 포인터 b은 요소 1에서 시작하여 size 번 진행될 것이므로 numbers[size+1]을 가리키게됩니다. 컴파일러가 쓸데없는 역 참조를 최적화하면 문제가되지 않지만 이전 패스에서는 swap(numbers+size-1, numbers+size)을 호출하면 배열의 끝에서 씁니다. 이로 인해 스택 손상이 감지됩니다.

2

연습으로 배열 정렬을 구현한다고 가정합니다. 이것은 정말로 당신의 질문에 대답하지 않지만, 나는 관계없이 참조 용으로 게시 할 것이라고 생각했습니다.

#include <iostream> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    int numbers[] = { 8, 16, 23, 487, 2, 301, 48, 0, 13, 10, 644, 12 }; 
    size_t const size = sizeof(numbers)/sizeof(numbers[0]); 

    int * const begin = numbers; 
    int * const end = numbers + size; 

    std::sort(begin, end); 
    std::copy(begin, end, std::ostream_iterator<int>(std::cout, "\n")); 
} 
+0

예선 (STL)입니다. 사이드 노트에서 그는'std :: set' 컨테이너를 사용하여이 전체 프로그램을 2 줄까지 사용할 수 있습니다. – AJG85

+0

@ AJG85 : STL은 실제로 규칙을 짓습니다. :) 'std :: set'에 대한 좋은 지적. – Void

관련 문제