Почему этот код не печатает мой массив? - PullRequest
1 голос
/ 15 августа 2011

У меня есть программа сортировки целочисленных массивов, но у меня есть проблема: всякий раз, когда я запускаю программу, я иногда получаю сообщение «Стек вокруг переменной« числа »был поврежден», а иногда просто многократно выводится число 8 ». Вот мой код (скомпилирован в Visual C ++ 2010):

#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");

}

Ответы [ 5 ]

2 голосов
/ 15 августа 2011

Я предполагаю, что вы реализуете сортировку массива в качестве упражнения. Это на самом деле не отвечает на ваш вопрос, но я думал, что выложу для справки, в любом случае. Вот один из способов достижения желаемого результата с помощью STL:

#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"));
}
2 голосов
/ 15 августа 2011

Во-первых, вы никогда не увеличиваете numToPrint, поэтому вы никогда не собираетесь печатать больше, чем значение numbers[0]. Как минимум измените свой код на:

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

Во-вторых, поскольку ваш цикл while использует тест i < size, вы на последней итерации цикла будете получать доступ к памяти вне numbers для вашего указателя b и, возможно, поменять его значение в последний слот numbers (т. е. где a указывает на). Вы хотите изменить свой тест на i < (size - 1), чтобы избежать этого сценария. Например, если в i == 0 у вас есть a = &numbers[0] и b = &numbers[1], то к моменту, когда i == 12, вы получите a = &numbers[12] и b = &numbers[13] ... значение, b в этом случае указывает на конец массива. В зависимости от того, как ваш компилятор настроил стек, и от того, как вы распределили numbers в стеке, это может фактически привести к хаосу в вашей программе, если вы в итоге наберете b, указывающим на структуры данных записи активации для Ваша main() функция, и, в свою очередь, портит ее.

0 голосов
/ 15 августа 2011

Я почти уверен, что у вас есть проблема с приоритетом оператора:

*b++;

Фактически, компилятор должен был предупредить вас об операторе без побочных эффектов (*).

Кроме того, указатель b выйдет из конца массива, поскольку он начинается с элемента 1 и продвигается size раз, в конечном итоге он указывает на numbers[size+1].Если компилятор оптимизирует бесполезное разыменование, это не будет проблемой, но на предыдущем проходе вы вызываете swap(numbers+size-1, numbers+size), и это записывает конец массива, вызывая обнаружение повреждения стека.

0 голосов
/ 15 августа 2011

Эта сортировка не будет работать, поскольку вы просматриваете список чисел только один раз, поэтому она поменяет местами соседние элементы, но не будет сортировать список (это своего рода половина реализации пузырьковой сортировки)

0 голосов
/ 15 августа 2011

Хорошо, что сразу бросается в глаза, это то, что вы никогда не увеличиваете numToPrint, поэтому он будет печатать числа [0], размер число раз.

Я бы переписал твой раздел печати на

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

С этим вы можете избавиться от раздела результатов печати вашего кода, так как вышеописанный способ является более чистым способом сделать то же самое.

Сообщение об ошибке, которое вы получаете, возможно, связано с тем, что вы пишете в те части памяти, которые вам не следует трогать. Это, вероятно, результат неправильного использования sizeof. Возвращает количество элементов в числах, а не объем памяти. Рекомендую проверить комментарии по актуальному вопросу для правильного решения вашего второго вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...