Почему это сравнение указателя / целочисленного значения вызывает ошибку сегментации? - PullRequest
3 голосов
/ 22 июня 2011

Я работаю над программой, которая генерирует ошибку сегментации, и я не могу понять, почему. Если я удаляю объявление указателя из «самой низкой» и «самой большой» переменных и использую их как целые числа без указателя, программа работает нормально.

Однако, как только я пытаюсь использовать указатели, возникают проблемы, и я получаю ошибку сегментации. Я понимаю, что это, вероятно, очень простая и хорошо решаемая проблема, но я попытался понять код, рассматривая другие подобные проблемы. Я еще не нашел решение своей проблемы. Также я не понимаю, что происходит не так.

Это код, генерирующий проблему (ссылка на полный исходный код приведена ниже):

     cout << "This is the array containing the random numbers:\n";
 for(int *i=numbers; i != numbers + arrLength; i++) {
     if((*i % 200) == 0 && *i > 200) {
         cin.get();
         cout << endl;
     }
     else
         cout << *i << ' ';

     // Get statistics
     // In the continuation of getting, lowest, largest then adding to sum.
     // THIS PART IS MAKING SEGMENTATION FAULT.
     if(*i < *lowest)
         lowest =  i;
     if(*i > *largest)
         largest = i;
     sum += *i;
 }

Переменная i указывает на старую ссылку, которая объявляется после ввода пользователя:

cout << "You entered: " << arrLength << "\n\n";

 int *numbers = new int[arrLength];

 // Fill the array with random numbers
 srand(time(NULL));
 int x;
 int range = 5001;
 for(int index=0; index<arrLength; index++){
     *(numbers + index) = rand() % range;
     x = rand() % 2;
     if(x > 0) {
         *(numbers + index) = *(numbers + index) * -1;
     }
 }

Пожалуйста, объясните, почему моя программа не работает и что я делаю неправильно. Как я уже говорил ранее, все работает, кроме:

if(*i < *lowest)
         lowest =  i;
     if(*i > *largest)
         largest = i;

Полный источник: http://pastie.org/2105963

Заранее спасибо по этому вопросу!

Ответы [ 6 ]

3 голосов
/ 22 июня 2011
int *largest = 0, *lowest = 0, sum = 0;

Это ваша проблема.Вы никогда не выделяете память и не назначаете им правильный адрес.И когда вы разыменовываете указатель NULL, как здесь

if(*i < *lowest) //lowest is NULL

, вы получаете неопределенное поведение, которое включает ошибку сегментации, носовые демоны и все остальное

2 голосов
/ 22 июня 2011

Не работает, потому что не сравнивает указатели.Вы сравниваете значения, хранящиеся по некоторым адресам памяти, которые, скорее всего, не принадлежат вашей программе, поэтому вы сбиты SIGSEGV.

Вы не можете получить доступ к памяти, которая не принадлежитпрограмма.

1 голос
/ 22 июня 2011

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

int *largest = 0, *lowest = 0, sum = 0;
1 голос
/ 22 июня 2011

Ваше программирование использует недопустимую память (самый низкий и самый большой указатель).Но!

Указатели в этом коде не нужны

На самом деле программа имеет сложность, которая не требуется.Зачем использовать указатель, когда вы можете использовать индексы?

Вероятно, вы обнаружили ошибку размещения / инициализации.

 for(int index=0; index<arrLength; index++){
     numbers[index] = rand() % range;
     x = rand() % 2;
     if(x > 0) {
         numbers[index] = numbers[index] * -1;
     }
 }

Для создания массива нужен только указатель.*

И, наконец, ваша программа будет проще:

int lowest =numbers[0], largest = lowest;
 for(int i=0; i < arrLength; i++) {
     int ii = numbers[i ];                      )
     if((ii % 200) == 0 && ii > 200) {
         cin.get();
         cout << endl;
     }
     else
         cout << ii << ' ';

     if(ii < lowest)
         lowest =  ii;
     if(ii > largest)
         largest = ii;
     sum += ii;
 }
1 голос
/ 22 июня 2011

lowest и largest инициализируются перед разыменованием их?Использование *lowest вызовет ошибку сегмента, если нижний не указывает на действительный адрес.

Вы можете попробовать установить lowest = largest = numbers; где-нибудь в начале.Может быть, это поможет вам.

0 голосов
/ 22 июня 2011

Вы инициализируете самый низкий и самый большой значения 0, и разыменование обращается к памяти через нулевой указатель, и поэтому оно падает. Попробуйте вместо этого:

if (!lowest || *i < *lowest)
    lowest =  i;
if (!largest || *i > *largest)
    largest = i;

или

int *numbers = new int[arrLength];
lowest = largers = numbers; // initialise to something non-null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...