Задать вопрос

Как исправить странные ошибки Си-кода?

Пытался реализовать алгоритм энигмы(шифровальной машины) на си. Существуют 6 массивов[75], которые нужно в рандомном порядке заполнить числами от 0 до 74, причем они не должны повторяться. Мной была написана функция, осуществляющая данное действие путем использования функции-генератора псвевдослучайных чисел. С одним массивом все работает нормально, заполняется так как нужно. Когда вызывается эта функция несколько раз (для заполнения 6-и массивов) начинает происходить какая-то чертовщина. Программа виснет, иногда вылетает ошибка сегментации, GNU Debugger начинает пропускать строки кода, также виснет. Что это может быть и с чем может быть связано?
[РЕШЕНО]: Все из-за неинициализированных переменых

Код 1 (работающий):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char enigma();
void filling(int *, int);
void main()
{
  enigma();
}
char enigma()
{
  int reflector[75], rotor1[75], rotor2[75], rotor3[75], rotor4[75], rotor5[75];
  filling(reflector, 5);
}
void filling(int rotor[], int randvalue)
{
  int tmp;
  int number;
  int findflag;
  int launchflag = 1;
  int i;
  srand(randvalue);
  while(launchflag)
{
  tmp = rand()%75;
  for(i; i<75; i++)
  {
    if(rotor[i]==tmp)
    {
      findflag = 1;
      break;
    }
  }
  if(findflag==0)
  {
    rotor[number] = tmp;
    number++;
    i=0;
  }
  if(findflag==1)
  {
    i=0;
    findflag = 0;
  }
    if(number == 74)
    {
      launchflag = 0;
    }


}
}


Код 2 (неработающий):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char enigma();
void filling(int *, int);
void main()
{
  enigma();
}
char enigma()
{
  int reflector[75], rotor1[75], rotor2[75], rotor3[75], rotor4[75], rotor5[75];
  filling(reflector, 5);
  filling(rotor1, 6);
  filling(rotor2, 7);
  filling(rotor3, 8);
  filling(rotor4, 9);
  filling(rotor5, 10);
}
void filling(int rotor[], int randvalue)
{
  int tmp;
  int number;
  int findflag;
  int launchflag = 1;
  int i;
  srand(randvalue);
  while(launchflag)
{
  tmp = rand()%75;
  for(i; i<75; i++)
  {
    if(rotor[i]==tmp)
    {
      findflag = 1;
      break;
    }
  }
  if(findflag==0)
  {
    rotor[number] = tmp;
    number++;
    i=0;
  }
  if(findflag==1)
  {
    i=0;
    findflag = 0;
  }
    if(number == 74)
    {
      launchflag = 0;
    }


}
}
  • Вопрос задан
  • 107 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
for(i; i<75; i++) - не инициализировано начальное значение i, с большой вероятностью будет вылет из-за попытки записи в чужую память.
Ответ написан
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
Куча не иницализированных локальных переменных. Эти переменные не обнуляются в языке Си. Там какой-то мусор. Может быть и 0, но это как повезет.
number - вы там присваиваете rotor[number] что-то, а чему оно равно? i в цикле, как Rsa97 сказал.

И вообще, вы с алгоритмом перемудрили. Вы случайно генерируете число, пока не найдете новое число в массиве.
Есть более элегантное решение:
Заполните массив числами от 0 до 74 подряд. Потом перемешайте его, как написанно в вики. Или можно совместить изначальное заполнение и перемешивание. Буквально, вся функция filling становится:
void filling(int rotor[], int randvalue)
{
  srand(randvalue);
  for(int i = 0; i < 75; ++i) {
    int j  = rand() % (i+1);
    rotor[i] = rotor[j];
    rotor[j] = i;
  }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы