Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1

Ошибка при работе с динамической памятью - 'Invalid pointer operatoion'

08.07.2011, 23:36. Показов 2004. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Столкнулся с такой проблемой - код исполняется правильно, но при закрытие программы вываливается ошибка(скрин прилогается). Я нашёл строку(67) на которую он ругается, но с первого взгляда там всё чисто и проблемы я не вижу. Буду признателен за совет, тк уже долго мучаюсь(...
Сразу прошу прощения за дилетантское оформление, только учусь.
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
 Memo1->Enabled = false;
 FILE *f1 = fopen("files/results.txt", "r");
 if (f1 == NULL)
 {
   Memo1->Lines->Add("Результатов пока нет, вам нужно пройти тест.");
 }
 else
 {
   int count = 0, count2 = 0;//Счётчик кол-ва символов их файла, счётчик строк.
   int buf = 0;
   do
   {
     getc(f1);
     ++count;
   }
   while(!feof(f1));
   fclose(f1);
   count--;//Сверху счёт шёл с единицы, в массивах выделение памяти идёт с нуля.
   //Memo1->Lines->Add(count);// count = 34 символам, считал включительно с 0 до '\0'
   FILE *f2 = fopen("files/results.txt", "r");
   char *res = new char [count];//Символьный массив для текста из файла.
   for (int i = 0; i <= count; ++i)
   {
     res[i] = getc(f2);
     if(feof(f1))
     {
       res[count] = '\0';
     }
   }
   //Memo1->Lines->Add(res);
   //Ok
   fclose(f2);
   for (int i = 0; i <= count; ++i)
   {
     if ((res[i] == '\n')||(res[i] == '\0'))
     {
       ++count2;
     }
   }
   count2--;//Так как массивы выделяют с нуля, а счёт шёл с единицы.
   //Memo1->Lines->Add(count2);
   //Ok
   int *num = new int[count2];
   for (int i = 0, j = 0; i < count, j <= count2; ++i)//счёт с единицыж
   {
     if ((res[i] == '\n')||(res[i] == '\0'))
     {
       num[j] = buf;
       buf = 0;
       ++j;
     }
     if ((res[i] != '\0')&&(res[i] != '\n'))++buf;
   }
   int j = 0;
   /*while (j<=count2){Memo1->Lines->Add(num[j]);j++;}
   Memo1->Lines->Add(num[0]+num[1]);*///В сумме 33, тк каждая строка считается с нуля.
   //Ok
   char **str = new char*[count2];
   for(int i = 0; i <= count2; ++i)
   {
     str[i] = new char[num[i]];
   }
   //Ok
   for (int i = 0, j = 0, k = 0; i <= count, k <= count, j <= count2; ++i)//Излишние условия для отладки.
   {
     str[j][k] = res[i];// Вот на это ругается, почему?
     ++k;
     if ((res[i] == '\n')||(res[i] == '\0'))
     {
       str[j][k] = '\0';
       ++j;
       k = 0;
     }
   }
   delete []res;
   res = NULL;
   for (int j = 0; j <= count2; ++j)
   {
     Memo1->Lines->Add(str[j]);
   }//*/
 }
Отладочный файл который она читает приложен.
Миниатюры
Ошибка при работе с динамической памятью - 'Invalid pointer operatoion'  
Вложения
Тип файла: txt results.txt (35 байт, 20 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.07.2011, 23:36
Ответы с готовыми решениями:

Ошибка при выполнении (invalid pointer operation)
Надо рандомезировать массив, первый раз получается, но когда нажимаю на кнопку второй раз выдает ошибку &quot;invalid pointer operation и...

Ошибка invalid pointer
Приветствую всех! Сделал задание для универа, все компилилось и выполнялось так, как надо. Сижу с linux(в qt creator). Но после того, как...

Компонент Label - ошибка Invalid pointer operation
Здравствуйте! Не подскажете, почему у меня косячат компоненты Label? Выдается ошибка Invalid pointer operation в строке: ...

18
 Аватар для OstapBender
594 / 532 / 76
Регистрация: 22.03.2011
Сообщений: 1,585
08.07.2011, 23:50
Цитата Сообщение от Whiteha Посмотреть сообщение
for (int i = 0; i <= count; ++i)
почему тут <= ?

ну вероятно на выход за границы массива ругается

Цитата Сообщение от Whiteha Посмотреть сообщение
char *res = new char [count];//Символьный массив для текста из файла. for (int i = 0; i <= count; ++i) { res[i] = getc(f2); if(feof(f1)) { res[count] = '\0'; } }
это типа чтение строки?)
есть fgets();
http://www.cplusplus.com/refer... dio/fgets/
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 00:10  [ТС]
Спасибо за ответ, да с fgets() вы абсолютно правы, ещё есть fscanf(), но топорная реализация не должна влиять на эту ошибку...
Не могли бы указать номер строки которая вас не устроила, и написать какое значение даёт выход за пределы массива?
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 00:24
Во всех случаях не <=, а <
Последний элемент в цикле - и есть выход за границы
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 00:42  [ТС]
Питекантроп, во всех случаях? До последнего цикла всё отлажено, там проблем с памятью быть не должно. Если сделать везде неравенство строгими, то будет нарушена логика и работать ничего правильно не будет.
Если вы имели ввиду последний цикл, то при заме неравенств
Цитата Сообщение от Whiteha Посмотреть сообщение
i <= count, k <= count
на строгие ошибка при выключении не пропадает.
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 00:47
Цитата Сообщение от Whiteha Посмотреть сообщение
char *res = new char [count];//Символьный массив для текста из файла.
индекс последнего элемента count-1
Всего-то count элементов
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 01:02  [ТС]
Прошу простить мне мою глупость, но что-то я вас не очень понимаю(
Вы имеете ввиду индекс последнего инициализированного значения? почему это он count-1? и как это может влиять?(хотя там такого быть не должно)
Укажите пожалуйста номера строк которые нужно править и как. В чём ошибка?(
Вероятно я что-то не так понимаю, напишите пожалуйста поподробнее, не хочется повторять эту ошибку в дальнейшем...
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 01:13
Цитата Сообщение от Whiteha Посмотреть сообщение
char *res = new char [count];//Символьный массив для текста из файла.
тут вы динамически создали массив. Его первый элемент будет res[0]. Последний - res[count-1].
res[count] уже за границами!

А вы во всех циклах к нему обращаетесь.

Поэтому нужно или сделать во ВСЕХ циклах строгое неравенство, чтоб не было ошибки, либо создавать массивы на один элемент больше
char *res = new char [count+1];
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 01:20  [ТС]
Питекантроп, не помогло, видимо ошибка не в этом...
На всякий случай поясню свои действия.
Я посчитал количество символов в файле, но счёт шёл с единицы, то есть получившийся count был на единицу больше чем нужно для задания массива под хранение всего файла.
Поэтому я понижаю его count--; и теперь массив выделяется ровно под размер файла( включая '\0').
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 01:29
Цитата Сообщение от Whiteha Посмотреть сообщение
count--;/
да, согласен

Цитата Сообщение от Whiteha Посмотреть сообщение
count2--;//Так как массивы выделяют с нуля, а счёт шёл с единицы.
//Memo1->Lines->Add(count2);
//Ok
int *num = new int[count2];
а тут?

Цитата Сообщение от Whiteha Посмотреть сообщение
char **str = new char*[count2];
for(int i = 0; i <= count2; ++i)
{
str[i] = new char[num[i]];
}
//Ok
Или тут?
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 01:40  [ТС]
C++
1
2
3
4
5
6
7
 for (int i = 0; i <= count; ++i)
   {
     if ((res[i] == '\n')||(res[i] == '\0'))
     {
       ++count2;
     }
   }
Здесь идёт подсчёт строк, счёт так же как и в первом случае начинается с единицы, массивы выделяются с нуля. Поэтому вновь:
C++
1
count2--;
Ну а здесь:
C++
1
2
3
4
5
char **str = new char*[count2];
 for(int i = 0; i <= count2; ++i)
 {
 str[i] = new char[num[i]];
 }
Я выделяю память под массив из count2 строк, каждая из которых num[i] длинной. И все размеры вроде как на месте.=/
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 01:48
Цитата Сообщение от Whiteha Посмотреть сообщение
char **str = new char*[count2];
for(int i = 0; i <= count2; ++i)
{
str[i] = new char[num[i]];
}
В цикле идет обращение к элменту str[count].

Цитата Сообщение от Whiteha Посмотреть сообщение
count2--;//Так как массивы выделяют с нуля, а счёт шёл с единицы.
int *num = new int[count2];
а тут-то вы сначала уменьшили count2, а потом массив сделали.
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 01:54  [ТС]
Ну у меня же значение count2 уменьшается сразу после получения и на всём оставшемся участке программы не изменяется, так что
Цитата Сообщение от Питекантроп Посмотреть сообщение
char **str = new char*[count2];
for(int i = 0; i <= count2; ++i)
{
str[i] = new char[num[i]];
}
идёт с тем же count2 что и здесь:

Цитата Сообщение от Питекантроп Посмотреть сообщение
count2--;//Так как массивы выделяют с нуля, а счёт шёл с единицы.
int *num = new int[count2];
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
09.07.2011, 02:45
i <= count2-1;
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 02:54  [ТС]
Хорошо, кто понял в чём ошибка, можете дать исправленную версию кода? Мои исправления по вашим советам не приносят положительных результатов.(
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 03:38
Whiteha,
загрузку из файла в мемо в билдере можно так
C++
1
Memo1->Lines->LoadFromFile("D:\\result.txt");


Если хотите самостоятельно разбить по строкам, то во вам такой код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Memo1->Enabled = false;
Memo1->Clear();
 FILE *f1 = fopen("D:\\result.txt", "r");
 if (f1 != NULL) 
 {
   char *res = new char[f1->bsize],**str,**s;
   fread(res,f1->bsize,1,f1);
   fclose(f1);
   int count2 = 1;
   for (char * x = res; *x; x++) if (*x=='\n') count2++;
   str = s = new char*[count2];
   *s = res;
   for (char * x = res; *x; x++) if (*x=='\n')
   {
        *x=0;
        *(++s) = x+1;
   }
   for (int j = 0; j < count2; ++j) Memo1->Lines->Add(str[j]);
   delete[]res;
   delete[]str;
 }
Только имя файла не забудьте свое поставить
1
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
09.07.2011, 11:58  [ТС]
Хоть я так и не понял где у меня там шёл выход, но спасибо за науку
Всё действительно можно расписать гораздо проще чем я расписал, LoadFromFile() я не пользовался, ибо хотел лишний раз поработать с массивами и перестать наконец выходить за их пределы(задача носит учебный характер).
Ну а ваш код в 21 строку, работает, но выводит пару мусорных строк.
P.S. Не теряю надежды, что меня ткнут носом в моём коде на ошибку и покажут исправление...
0
 Аватар для Питекантроп
251 / 145 / 21
Регистрация: 14.06.2010
Сообщений: 340
09.07.2011, 16:59
Цитата Сообщение от Whiteha Посмотреть сообщение
Ну а ваш код в 21 строку, работает, но выводит пару мусорных строк.
Вот в таком виде должен не выводить

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Memo1->Clear();
 FILE *f1 = fopen("D:\\result.txt", "r");
 if (f1 != NULL)
 {
   fseek(f1, 0, 2);
   int count = ftell(f1),count2 = 1;
   rewind(f1);
   char *res = new char[count],**str,**s;
   fread(res,count,1,f1);
   fclose(f1);
   for (char * x = res; *x; x++) if (*x=='\n') count2++;
   str = s = new char*[count2];
   *s = res;
   for (char * x = res; *x; x++) if (*x=='\n')
   {
        *x=0;
        *(++s) = x+1;
   }
   for (int j = 0; j < count2; ++j) Memo1->Lines->Add(str[j]);
   delete[]res;
   delete[]str;
 }

Цитата Сообщение от Whiteha Посмотреть сообщение
P.S. Не теряю надежды, что меня ткнут носом в моём коде на ошибку и покажут исправление...
Пользуйтесть отладчиком.
Или можете просто расставлять мессаджбоксы в разных местах кода, чтоб узнать до куда доходит код.
Application->MessageBoxA("блаблабла","",0);
1
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
10.07.2011, 22:00  [ТС]
Питекантроп, эта версия полностью рабочая, спасибо=)
А со своим кодом - у меня весь код проходит и всё выполняется без ошибок, ошибка возникает лишь при завершении программы, закрытие формы. От ошибки избавляет лишь "закоменчивание" 67 строки, но почему это так мне выяснить не удалось.

Добавлено через 23 часа 27 минут
Ещё актуально(напомню, мучаюсь в учебных целях, альтернативные варианты - хорошо, но я очень хочу понять в чём просчёт и как его устранить).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.07.2011, 22:00
Помогаю со студенческими работами здесь

Что за ошибка "invalid pointer addition"
Код: Form9-&gt;ADOQuery1-&gt;Close(); Form9-&gt;ADOQuery1-&gt;SQL-&gt;Text = &quot;SELECT SUM(Сума) AS Сума FROM WHERE Код_чека=:N;&quot;; ...

Что за ошибка "invalid pointer addition"
Что за ошибка? ServChat.cpp(114): E2085 Invalid pointer addition че с ней делать?

Ошибка "invalid pointer addition"
//--------------------------------------------------------------------------- #include &lt;vcl.h&gt; #include &lt;math.h&gt; #pragma hdrstop ...

Ошибка "Invalid pointer addition"
Все переменые одного типа. Ругается на конкатенацию &quot;key=&quot; и KeyT key=&quot;key=&quot;+keyT; text=&quot;text=&quot;+InTex; Добавлено через 18...

Ошибка в коде при работе с динамической памятью
Не могу понят что не так ? При вводе в динамический массив А последовательность &quot;61 3 2 0 -2 -25 -61 -70&quot; программа крашится...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru