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

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

08.07.2011, 23:36. Показов 2024. Ответов 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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru