Форум программистов, компьютерный форум CyberForum.ru

Бинарные файлы и Stack around the variable was corrupted - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.94
Borsch
 Аватар для Borsch
0 / 0 / 0
Регистрация: 20.05.2011
Сообщений: 10
04.06.2011, 15:48     Бинарные файлы и Stack around the variable was corrupted #1
Добрый день.
Делаю программу (лабу), которая работает с бинарными файлами:
Сначала заполняет бинарный файл случайным количеством случайных чисел, а затем - считывает этот файл, из последних его элементов строит матрицу из 25 элементов (5х5), а также подсчитывает сумму отрицательных элементов под главной диагональю.
Компилятор MS Visual Studio 2010 при выходе из функции SetTheFile ругается на переменную buffer.
Пишет диалоговое окно: Stack around the variable 'buffer' was corrupted.
Подскажите, отчего это и как можно исправить?
Причем, если в этом диалоговом окне нажать Continue - программа продолжит работать как положено.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
#include <fstream>
#include <stdio.h>
//#include <iomanip>
 
using namespace std;
#define BEFFERATOR 2
#define randomize() (srand(time(0))) 
 
int SetTheFile();
int SetTheMatrix();
 
//шапка-меню
int main() 
{cout<<endl<<"=Work with Binary Files="<<endl;
  int choiz;
  while (true) 
  {
 
    cout<<endl<<"Input 1 to create binary file"<<endl;
    cout<<"Input 2 to set matrix from file"<<endl;
    cout<<"Input 3 EXIT!"<<endl<<endl;
    //  srand(time(0));
 
 
    while (true) 
    {
      cout<<"Think wisely and make your choice: ";
      cin>>choiz;
      if (choiz==1 || choiz==2 || choiz==3) break;
      cout<<"Error. So sad."<<endl;
    }
    switch (choiz) 
    {
      case 1: SetTheFile();    break;
      case 2: SetTheMatrix();  break;
      case 3: return 0;
      default: continue;
    }
  }
}
 
int SetTheFile() 
{
//  system("cls");
 
  FILE *p=fopen("sardelki.bin", "wb");
  
  char buffer[BEFFERATOR];
 
  int j;
  j=rand()%10 + 20;
  cout<<endl<<" Chisel zadano: "<<j<<endl;
 
  for (int i=0; i<j; i++) 
  {
     
    itoa(rand()%10-5,buffer,10);
    fwrite (buffer, 1, sizeof(buffer), p);
 
    printf("%s ", buffer);
  }
  if (j<25)
  {
  cout<<endl<<"WARNING! Chisel menshe 25. Matrix uncreateble";
  cout<<endl<<"Recomendutsa poprobovat' escho raz";
  }
  fclose (p);
  printf("\n");
  system("pause");
  
  return 0;
} //Ругается прям в этой строке===========================================
 
int SetTheMatrix() 
{
  //system("cls");
 
  FILE *p=fopen("sardelki.bin", "rb");
  
 // rewind(p);
  fseek(p, 0, SEEK_SET);
  char buffer[BEFFERATOR];
  int numbers[5][5]={0};
  int i, j;
  printf("Matrix, built from binary p:\n");
  for (i=0; i<5; i++) {
    for (j=0; j<5; j++) {
      fseek(p, EOF-1-BEFFERATOR*(i*5+j), SEEK_END);
      fread (buffer, 1, sizeof(buffer), p);
      numbers[i][j]=atoi(buffer);
      //atoi = string -> integer, int
      printf("%4d ", numbers[i][j]);
    }
    printf("\n");
  }
  fclose (p);
 
  int sum=0;
  for (i=1; i<5; i++)
    for (j=0; j<i; j++)
        if (numbers[i][j]<0)
      sum+=numbers[i][j];
  printf("Sum: %d.", sum);
 
  printf("\n");
  system("pause");
  return 0;
}
Приму критику и советы по оптимизации кода) Ибо громоздко как-то оно всё. Но главная цель - исправить краш стека.
И еще дополнительно интересует... как реализовать, чтобы строить матрицу не с конца файла, а с элемента файла, указанного пользователем? Т.е. задаст счетчик рандомно 50 чисел, пользователь введёт например число 10, и чтоб матрица 5х5 составлялась из элементов с 10 по 35.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.06.2011, 15:48     Бинарные файлы и Stack around the variable was corrupted
Посмотрите здесь:

C++ Stack around the variable 'b' was corrupted
stack around the variable was corrupted C++
Stack around the variable 's' was corrupted C++
C++ Stack around the variable was corrupted
C++ Stack around the variable 'cif' was corrupted
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
bigredcat
364 / 311 / 3
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
04.06.2011, 16:27     Бинарные файлы и Stack around the variable was corrupted #2
rand()%10-5 может быть отрицательным, например, -5.
sizeof("-5") == 3
sizeof(buffer) == 2, т.к. BEFFERATOR == 2

Цитата Сообщение от Borsch Посмотреть сообщение
Stack around the variable 'buffer' was corrupted
Вообще, получив такое сообщение, логично было сразу увеличить размер buffer
А выполняется нормально потому, что в стеке все-равно занимает 4 байта (или даже 8), а не 2. Это, кстати, на будущее, если нет особых причин ограничивать размер, то лучше устанавливать его кратным 4 (8) байтам
Borsch
 Аватар для Borsch
0 / 0 / 0
Регистрация: 20.05.2011
Сообщений: 10
04.06.2011, 16:33  [ТС]     Бинарные файлы и Stack around the variable was corrupted #3
Да, верно. Еще подсказали про
C++
1
itoa(rand()%10-5,buffer,10);
т.к. отрицательное число с концом строки (нуль-символом) займёт 3, при размере buffer == 2.
Собственно да, одно и то же.

Не могу понять, как подправить buffer не порушив всё остальное?
Т.е. значение buffer необходимо выставить равное 3.
Если я так делаю - рушится построение матрицы. Числа в ней получаются левые.
bigredcat
364 / 311 / 3
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
04.06.2011, 16:52     Бинарные файлы и Stack around the variable was corrupted #4
Оставьте только от 0 до 9
C++
1
itoa(rand()%10,buffer,10);
Добавлено через 2 минуты
А вообще если вы измените так, то и с матрицей (думаю) все нормально будет
C
1
#define BEFFERATOR 8
Borsch
 Аватар для Borsch
0 / 0 / 0
Регистрация: 20.05.2011
Сообщений: 10
04.06.2011, 16:54  [ТС]     Бинарные файлы и Stack around the variable was corrupted #5
UPD Спасибо, получилось. Установил размер #define BEFFERATOR 4, вместо #define BEFFERATOR 2.
А строку fseek(p, EOF-1-BEFFERATOR*(i*5+j), SEEK_END); заменил на fseek(p, EOF-3-BEFFERATOR*(i*5+j), SEEK_END);

Благодарю за наводку про нуль-символы и размер буфера.

А про навигацию (построение матрицы с элемента, указанного пользователем) такая идея:
Задаются рандомное кол-во случайных чисел, пользователь указывает номер элемента, с которого начать строительство матрицы. Перемещаюсь к этому элементу используя fseek. Матрица состоит из 25 символов. Задаю счетчик counter=1 и цикл while (counter!=25), внутри которого идёт строительство таблицы и увеличение счетчика на 1.
Таким образом отмерится ровно 25 элементов. Вроде так. Сейчас проверю.

Добавлено через 1 минуту
не успел отредактировать прошлое сообщение, таймаут 10 мин истёк)
Использовать только положительные числа не могу - в задании еще указано подсчитать сумму отрицательных элементов под главной диагональю. Но теперь даже с отрицательными всё хорошо.
bigredcat
364 / 311 / 3
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
04.06.2011, 17:04     Бинарные файлы и Stack around the variable was corrupted #6
Не совсем понимаю, что вы этим хотите добиться
C++
1
fseek(p, EOF-3-BEFFERATOR*(i*5+j), SEEK_END)
Borsch
 Аватар для Borsch
0 / 0 / 0
Регистрация: 20.05.2011
Сообщений: 10
04.06.2011, 17:40  [ТС]     Бинарные файлы и Stack around the variable was corrupted #7
Построения матрицы.

начинаю с int numbers[5][5]={0};
задаю двумерный целочисленный массив numbers, счетчики i и j.
Далее два цикла For, дабы пройтись по каждому элементу матрицы, начиная с [0][0] кончая [4][4].
В циклах - установка позиции указателя/каретки символа/курсора (грубо говоря).
С помощью fseek (указатель на файл, Конец_файла - 3 - размер_буфера*(номер_строки*5-номер_столбца), с конца файла).
Т.е. это представление двумерного массива в виде линейного, чтоли... Как бэ взяли и вытянули квадратную матрицу в одну строку, где любой элемент можно найти по формуле i*5-j, где 5 это размерность матрицы. Ведь в файле, который надо прочитать, символы (числа) записаны последовательно. Вот и тут, я, например, при i==0 и j==0, я через fseek считываю с конца файла следующее: Конец_файла - 3 - 4*(0*5-0). Т.е. Конец_файла - 3. В файле на этой позиции как раз записано последнее число. Я его читаю и складываю в buffer, а затем элементу массива number[i][j] присваиваю значение buffer.

UPD выглядит это так: http://s2.ipicture.ru/uploads/20110604/NGVCsLNg.jpg
Последние цифры в файле - это первые цифры в матрице. По строкам.

Добавлено через 20 минут
Ну тогда ещё небольшой вопрос - в бинарных файлах while(!feof (file) ) работает так же, как в текстовых?
Хотел при чтении файла, перед построением матрицы, вывести на экран всё содержимое файла.
Почему-то при чтении этого бинарника в цикле while (!feof () ) последний символ считывается два раза. Это не мешает построению матрицы, но, согласитесь, выглядит неприлично. Скриншот здесь, 121 килобайт http://s2.ipicture.ru/uploads/20110604/AiUU0dTw.jpg
bigredcat
364 / 311 / 3
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
04.06.2011, 18:24     Бинарные файлы и Stack around the variable was corrupted #8
Вообще то EOF это константа, символ конца файла, по-моему равен -1.
Так что получается, что
C++
1
fseek(p, EOF-3-BEFFERATOR*(i*5+j), SEEK_END)
равносильно
C++
1
fseek(p, -4-BEFFERATOR*(i*5+j), SEEK_END)
Вот и вопрос, зачем вы это делаете.

И зачем вы в бинарный файл сохраняете текстовые представления целых чисел. Сохраняйте сразу числа и используйте тогда sizeof (int), а не sizeof (BEFFERATOR).

А конец файла он и в бинарных файлах конец файла.
Borsch
 Аватар для Borsch
0 / 0 / 0
Регистрация: 20.05.2011
Сообщений: 10
04.06.2011, 18:41  [ТС]     Бинарные файлы и Stack around the variable was corrupted #9
Проверил, EOF действительно равен -1. Спасибо, не знал.
Теперь смысл этого смещения стал понятнее.
Но, в принципе, EOF уже и не нужен особо, ведь я стараюсь сделать построение с элемента по заявке пользователя.
Пока безуспешно. Т.е. например юзер вводит 6. Значит, строить матрицу начинать с 6 элемента. fseek (p, U*BEFFERATOR, SEEK_SET);. Только надо как-то увязать это с i и j, аналогично как было с EOF.

Цитата Сообщение от bigredcat Посмотреть сообщение
А конец файла он и в бинарных файлах конец файла.
Хм.. Чего же он тогда выводит лишний символ? Это проблема записи в файл или чтения из файла?
bigredcat
364 / 311 / 3
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
04.06.2011, 18:58     Бинарные файлы и Stack around the variable was corrupted #10
Вам не нужно заморачиваться на i, j. Ведь пользователь вводит номер элемента в массиве.
Просто устанавливаете указатель в файле на нужный элемент и начинаете чтение, указатель будет сдвигаться автоматически.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
fseek(p, (номер_введенный_пользователем - 1) * sizeof (BEFFERATOR)), SEEK_SET);
for (i=0; i<5; i++)
{
    for (j=0; j<5; j++)
//  можно еще проверку вставить, я не вникал, как вы там проверяете размер массива и конец файла.
//  for (j=0; j<5 && !feof(p); j++)
    {
        fread (buffer, 1, sizeof(buffer), p);
        numbers[i][j] = atoi(buffer);
        printf("%4d ", numbers[i][j]);
    }
    printf("\n");
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2011, 19:13     Бинарные файлы и Stack around the variable was corrupted
Еще ссылки по теме:

C++ stack around the variable was corrupted масив через указатель
C++ Stack around the variable was corrupted
Stack around the variable 'stat_c1' was corrupted C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Borsch
 Аватар для Borsch
0 / 0 / 0
Регистрация: 20.05.2011
Сообщений: 10
04.06.2011, 19:13  [ТС]     Бинарные файлы и Stack around the variable was corrupted #11
Заморочился с i и j, вышло таким вот образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 cout<<"S kakogo elementa stroit' martix?"<<endl;
 cin>>U;
 int counter=0;
 
  int numbers[5][5]={0};
  int i, j;
  printf("Matrix, built from binary file :\n");
 
 
  for (i=0; i<5; i++) 
  {
    for (j=0; j<5; j++) 
    { 
      fseek(p, U*BEFFERATOR+BEFFERATOR*(5*i+j), SEEK_SET);      
      //  EOF-3-BEFFERATOR*(i*5+j)
      fread (buffer, 1, sizeof(buffer), p);
      numbers[i][j]=atoi(buffer);
      //atoi = string -> integer, int
      printf("%4d ", numbers[i][j]);
    }
    printf("\n");
  }
Всё работает как часы. Спасибо за поддержку!
Yandex
Объявления
04.06.2011, 19:13     Бинарные файлы и Stack around the variable was corrupted
Ответ Создать тему
Опции темы

Текущее время: 23:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru