Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181

Дайте ссылку или пример на интересующий меня вопрос.

10.02.2011, 13:55. Показов 2314. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
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
//Мне нужно сохранить информацию в массив структур FRAGMENT.
//Сруктура выглит так:
struct  FRAGMENT {
    int counter;        // счетчик, показывает номер фрагмента
    int Size_X;         // размер фрагмента по Х
    int Size_Y;        // размер фрагмента по Y
    char *lpBuffer;        // здесь хранятся символы
};
 
//Я обьявляю указатель на этот массив FRAGMENT.
FRAGMENT *mf;
 
//Дальше есть функция которая должна занести информацию в  мой массив структур.
//я описал эту функцию примерно так:
FRAGMENT *ReadBuffer(FRAGMENT *Buffer)
{
    int x;//как-то считается
    Buffer = new FRAGMENT[x];
    for(int i=0; i<x; i++)
    {
        Buffer[i].counter = i;
        //
        //
        Buffer[i].lpBuffer = new char[number];//number - какоето число
        //дальше вызывается функция которая занесла информацию в Buffer[i].lpBuffer
    }
    return Buffer;    
} 
 
//Вот так использовал функцию
mf = ReadBuffer(mf);
 
//Я уже понял что я что-то не так делаю, подскажите (просто на словах или ссылку на пример) как правильно организовать программу. Где поставить delete и почему.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.02.2011, 13:55
Ответы с готовыми решениями:

Дайте ссылку на пример unit теста
Можете дать ссылку на пример проекта, где используется jUnit для тестирования логики какого нибудь фрагмента приложения? Я просто хочу...

Дайте ссылку на скачивание PyQt-library. Ну или ссылку на сайт (Заранее спасибо)
Ссылку на сайт Qt-library

Дайте ссылку с примерами или сами примеры работы с ячейками в Excel
Народ, дайте ссылку с примерами или сами примеры работы с ячейками в Екселе из VB.Net 2010. Но в первую очередь прошу разобраться с...

20
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
10.02.2011, 14:06
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void ReadBuffer(FRAGMENT*& Buffer, int& x)
{
    // x как-то считается
    Buffer = new FRAGMENT[x];
    for(int i=0; i<x; i++)
    {
        Buffer[i].counter = i;
        //
        //
        Buffer[i].lpBuffer = new char[number];//number - какоето число
        //дальше вызывается функция которая занесла информацию в Buffer[i].lpBuffer
    }
} 
 
void ReleaseBuffer(FRAGMENT* Buffer, int x){
    for(int i=0; i<x; i++)
    {
        delete Buffer[i].lpBuffer;
    }
    delete[] Buffer;
}
можно и на указателях все, но лень было править
1
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 14:15  [ТС]
За пример спасибо.
Цитата Сообщение от alex_x_x Посмотреть сообщение
можно и на указателях все, но лень было править
А можно хотябы на словах как это все должно происходить при использовании указателей или где почитать.
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
10.02.2011, 14:27
почитайте про утечки памяти
например
http://www.cyberguru.ru/progra... -leak.html
http://cppworld.h16.ru/stdc/memory.htm
http://www.amse.ru/courses/cpp1/2009.10.19.html
http://www.intuit.ru/departmen... aldata/27/

здесь надо понимать уровень на котором ведется разговор
первоначально важно понимать как правильно работать с указателями, когда можно и нужно их освобождать
далее идут вопросы как не нужно работать с указателями, когда не нужно, смарт поинтеры и так далее
определитесь с общими понятиями в них даются общие правила работы
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 14:37
QWAN, вы писали:
C++
1
2
//Я обьявляю указатель на этот массив FRAGMENT.
FRAGMENT *mf;
Указатель-то вы объявили, а сам массив не создали.

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
FRAGMENT *mf = 0;
int mf_size = 0;
 
//...
void construct_fragment( int size )
{
   mf_size = size;
   mf = new FRAGMENT[ size ];
}
 
void delete_fragment()
{
   mf_size = 0;
   delete [] mf;
   mf = 0;
}
 
void cout_all_fragments()
{
   if(mf == 0) return; //нулевой указатель. объекта не существует.
 
   for( int i = 0; i < mf_size; i++ )
   {
      cout << mf[i].Size_X;
      //...
   }
}
В этом случае int counter вам не нужен (если, конечно, вы не связанный список делаете. А вы, вроде, не связанный список делаете )

На словах: указатель - переменная, хранящая в себе адрес какого-то объекта. То, что вы выделили 4 байта под указатель, ещё не значит, что выделили 32 байта под объект (или сколько он там у вас занимает) или 32*8 байт на массив объектов из 8 элементов.

Память выделяется динамически - (через "new", освобождается через "delete []" для массивов или "delete" для единичных объектов). Когда вы пишите "char * ptr;" вы создаёте указатель на объект(ы) типа char. Но вам ведь ещё сами объекты создать нужно, верно? "ptr = new char[256];" Когда они вам перестают быть нужны, удалите их: "delete [] ptr;". Так же хорошим тоном считается инициализировать указатели нулём и при удалении объектов, на которые они указывают, так же обнулять их.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
10.02.2011, 14:38
QWAN, если хотите сохранять в файл массив структур, лучше в структуре поле char *lpBuffer; сделать не указателем, а массивом
C
1
char szBuffer[SOME_PREDEFINED_SIZE];
тогда получится что-то вроде
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
typedef struct  FRAGMENT {
    int counter;        // счетчик, показывает номер фрагмента
    int Size_X;         // размер фрагмента по Х
    int Size_Y;        // размер фрагмента по Y
    char szBuffer[SOME_PREDEFINED_SIZE];        // здесь хранятся символы
}fragment_t; // так привычнее и удобнее
 
...
 
fragment_t stat_fragments[NUMBER_OF_FRAGMENTS];
fragment_t * dyn_fragments = (fragment_t*)calloc(NUMBER_OF_FRAGMENTS, sizeof(fragment_t)); 
// на самом деле нужно проверить, удачно ли память выделилась
...
// чем-то как-то заполняем массив(ы)
// пишем в файл
FILE * f = fopen(FILE_NAME, "wb"); // то же замечание по поводу проверки
fwrite(stat_fragments, NUMBER_OF_FRAGMENTS, sizeof(fragment_t), f); 
// возвращённое значение должно ровняться NUMBER_OF_FRAGMENTS
fwrite(dyn_fragments, NUMBER_OF_FRAGMENTS, sizeof(fragment_t), f); 
// возвращённое значение должно ровняться NUMBER_OF_FRAGMENTS
fclose(f);
...
// чтение
f = fopen(FILE_NAME, "rb");
fread(stat_fragments, NUMBER_OF_FRAGMENTS, sizeof(fragment_t), f); 
// возвращённое значение должно ровняться NUMBER_OF_FRAGMENTS
fread(dyn_fragments, NUMBER_OF_FRAGMENTS, sizeof(fragment_t), f); 
// возвращённое значение должно ровняться NUMBER_OF_FRAGMENTS
fclose(f);
// и снова повторюсь - не забывайте проверять ВСЕ значения, возвращаемые функциями ввода-вывода
0
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 15:20  [ТС]
Цитата Сообщение от talis Посмотреть сообщение
Указатель-то вы объявили, а сам массив не создали.
В функции ReadBuffer я и создавал сам массив
Buffer = new FRAGMENT[x];

В принципе программа нормально работала, пока я незахотел с помощю этой функции инициализировать еще один массив.
Тогда то я и понял что абсолютно ничего непонимаю и не только с операторами new и delete.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 15:30
Да, действительно. Извините. Просто сбивает с толку
C++
1
FRAGMENT *ReadBuffer(FRAGMENT *Buffer)
Зачем тогда параметр? можно ведь
C++
1
2
3
4
5
6
FRAGMENT * ReadBuffer()
{
   FRAGMENT * Buffer = new FRAGMENT[x];
   //...
   return Buffer;
}
Но вообще обычно делают так:
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
bool ReadBuffer( FRAGMENT * Buffer, int size )
{
   if( Buffer == 0 || size == 0 )
      return false;
 
   for(int i = 0; i < size; i++)
   {
        Buffer[i].counter = i;
        //
        //
        Buffer[i].lpBuffer = new char[number];//number - какоето число
        //дальше вызывается функция которая занесла информацию в Buffer[i].lpBuffer
   }
 
   return true;
}
 
void foo()
{
   FRAGMENT * local_buffer = new FRAGMENT[15];
 
   if( false == ReadBuffer( local_buffer, 15 ) )
      cout << "Error reading buffer. Probably local_buffer is not initialized" << endl;
 
   delete [] local_buffer;
}
 
//или:
 
void bar()
{
   FRAGMENT local_buffer[15];
 
   if( false == ReadBuffer( local_buffer, 15 ) )
      cout << "This should not happen!!!" << endl;
}
1
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:09  [ТС]
Давайте начну сначала, я попробую расказать чего я хочу добиться от своей программы.
Допустим есть консольное приложение с большим буфером экрана (назовем ее плоскостью А). Я создаю дополнительную плоскость тоже большого размера, назовем ее Б. Чтобы скопировать с плоскости Б на плоскость А определенный прямоугольник символов с их атрибуми использую функции ReadConsoleOutput и WriteConsoleOutput. Эти функции имеют ограничение по размеру буффера 64К. Чтобы преодолеть это ограничение я придумал свою структуру FRAGMENT.

Массив из структур FRAGMENT тепер есть мой буффер, который может быть ограничен в принципе только размером свободной памяти компютера.
Я создаю указатель на мой буфер. Но размера я его еще незнаю. Функция
Код C++
1 FRAGMENT * ReadRectSurface(HANDLE hSurface, SMALL_RECT lpReadRegion, FRAGMENT *pBuffer)

должна была вычислить по заданному размеру прямоугольника:
1) количество элементов в массиве. ЕСЛИ оно меньше 64К то всего один элемент;
2) выделить для массива память;
3) если размер прямоугольника больше 64К, я пробую разбить прямоугольник построчно, если и этот размер больше 64К то выдать ошибку (можно былобы и далее дробить но пока этого достаточно). Иначе, выделить память размером в длину строки. На эту память указывает последний указатель в моей структуре.
C++
1
2
3
4
5
6
//стуктура предназначена для хранения части поверхности или всей поверхности если ее размер не превышает LIMIT
typedef struct _FRAGMENT {
    int counter;                // счетчик, показывает сколько фрагментов находится после текущего
    COORD dwBufferSize;         // размер фрагмента
    CHAR_INFO *lpBuffer;        // буфер данных, здесь хранятся символы
} FRAGMENT, *PFRAGMENT;
Осталось определить что передавть в функцию ReadRectSurface , что она должна возвращать, и где сделать очистку памяти.
0
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:12  [ТС]
Навсякий случай прикреплю програмку, так будет более понятно. Она работает, только на чсном слове.
Вложения
Тип файла: rar main_control.rar (2.6 Кб, 19 просмотров)
0
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:15  [ТС]
Цитата Сообщение от easybudda Посмотреть сообщение
если хотите сохранять в файл массив структур, лучше в структуре поле char *lpBuffer; сделать не указателем, а массивом
Дело в том что я незнаю в определенный момент размер этого массива. Он вычисляется по ходу работы.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 16:19
QWAN, 64 Кб * 1024 = 65536 байт. Вы действительно думаете, что вам не хватит?

Добавлено через 17 секунд
Попробую вникнуть в вашу проблему...
0
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:29  [ТС]
Цитата Сообщение от talis Посмотреть сообщение
64 Кб * 1024 = 65536 байт. Вы действительно думаете, что вам не хватит?
Максимум что у меня получилось скопировать (по памяти) это прямоугольник 140 * 95. хотя он и немного меньше чем 64К. Причину я так и неустановил.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 17:07
Посмотрел я вашу программу. Вам удалось записать прямоугольник в 400 байт. Это действительно немного меньше 64 килобайт
Существенные корректировки пометил как MY_EDIT: в комментарии. Решении проблем с вылетом пометил как SOLUTION:
Вообще, пол-программы пришлось перелопатить. Если что - спрашивайте.
Вложения
Тип файла: zip main.zip (3.2 Кб, 15 просмотров)
1
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 18:36  [ТС]
Спасибо, за переделанную програмку. Пока только смотрю что переделали. Вопросы чуть позже напишу, когда более вникну.
Цитата Сообщение от talis Посмотреть сообщение
Вам удалось записать прямоугольник в 400 байт. Это действительно немного меньше 64 килобайт
.
Это только для пробы, прямоугольник только ведь 10х10.
sizeof (CHAR_INFO) равен 4 байтам, 65536 / 4 = 16384 ячейки cимволов. Если 200*82 = 16400 то уже превышен лимит. У меня раскрывая консольное окно на весь экран (22") получаю разрешение в символьных ячейках 240*95 = 22800, 22800 * 4 = 91200 байт.

Добавлено через 36 минут
Досмотрел програмку, спасибо большое за исправленные ошибки.
Код C++
1 int lpBufferSize; // MY_EDIT: размер буфера данных

Думаю, это лишняя переменная в структуре, она избыточна, достаточно ширины на высоты и sizeof (CHAR_INFO).

Вариант с применением глобальной переменной Код C++
1 int arraySize;

мне понравился, удаляется переменная из структуры.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 18:47
Вариант с применением глобальной переменной
int arraySize;
мне понравился, удаляется переменная из структуры.
Это нормальная практика, когда рядом с динамически выделенным массивом лежит его размер.

int lpBufferSize; // MY_EDIT: размер буфера данных
Думаю, это лишняя переменная в структуре, она избыточна, достаточно ширины на высоты и sizeof (CHAR_INFO).
Да, данные возможно рассчитать. На самом деле, это вопрос баланса между производительностью и расходом памяти, на этот счёт некоторые программисты спорят до хрипоты: с одной стороны - лишние 4 байта на каждый элемент массива, с другой - каждый раз рассчитывать, лишние итерации. В данном случае это не критично, поэтому я руководствуюсь рекомендациями Бьерна Страуструпа: писать код, понятный человеку. Мне так было понятнее, но дело ваше .

Добавлено через 6 минут
Попробуйте посмотреть в сторону curses - очень умная библиотека, к тому же кроссплатформенная. Для Windows есть pdcurses.
0
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 19:01  [ТС]
Думаю чтобы использовать сторонние библиотеки я еще не дорос (мало знаний и опыта). Программирование для меня просто увлечение. Сейчас пытаюсь сделать простой ASCII редактор с панелью инструментов, окнами и каким-то проигывателем ASCII анимации. Заодно осваиваю и практикуюсь в програмировании. Насчет писать кросплатформенные програмки пока только мечтаю, но библиотеку Curses всеравно посмотрю.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 19:33
Да, много же вы мучаться будете, если будете писать ASCII-редактор с панелью инструментов, используя стандарнтый вывод! Тогда вам что-то, кроме curses, просто противопоказано!
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
11.02.2011, 04:11
Цитата Сообщение от QWAN
1 int lpBufferSize; // MY_EDIT: размер буфера данных

Думаю, это лишняя переменная в структуре, она избыточна
C++
1
2
3
4
5
6
struct  FRAGMENT {
    int counter;        // счетчик, показывает номер фрагмента
    int Size_X;         // размер фрагмента по Х
    int Size_Y;        // размер фрагмента по Y
    char *lpBuffer;        // здесь хранятся символы
};
каким образом программа будет определять, сколько символов хранится в lpBuffer ?
при сохранении символов в lpBuffer, каким образом программа будет определять, что не произошло переполнение lpBuffer ?
0
63 / 62 / 6
Регистрация: 02.09.2008
Сообщений: 181
11.02.2011, 10:17  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
каким образом программа будет определять, сколько символов хранится в lpBuffer ? при сохранении символов в lpBuffer, каким образом программа будет определять, что не произошло переполнение lpBuffer ?
Уменя пока реализовано так:
C++
1
pBuffer->lpBuffer = new CHAR_INFO [RegionSize.X * RegionSize.Y];
Talis когда исправлял мою програмку, добавил переменную для для определения размера буфера.

Цитата Сообщение от talis Посмотреть сообщение
Это нормальная практика, когда рядом с динамически выделенным массивом лежит его размер. int lpBufferSize; // MY_EDIT: размер буфера данных Думаю, это лишняя переменная в структуре, она избыточна, достаточно ширины на высоты и sizeof (CHAR_INFO). Да, данные возможно рассчитать. На самом деле, это вопрос баланса между производительностью и расходом памяти, на этот счёт некоторые программисты спорят до хрипоты: с одной стороны - лишние 4 байта на каждый элемент массива, с другой - каждый раз рассчитывать, лишние итерации. В данном случае это не критично, поэтому я руководствуюсь рекомендациями Бьерна Страуструпа: писать код, понятный человеку. Мне так было понятнее, но дело ваше . Добавлено через 6 минут.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.02.2011, 10:17
Помогаю со студенческими работами здесь

Как создавать xla-файлы? Расскажите, плз, или дайте ссылку! (-)
-

Дайте исходник или полный пример авторизации API контакта
Дайте исходник или полный пример авторизации API контакта с получением сообщений ?

Не понимаю алгоритм бинарного поиска, объясните или дайте ссылку на понятный материал
Читаю книгу: &quot;Грокаем алгоритмы&quot;, и не понял раздел про бинарный поиск, объясните как работает. На python 3, это важно!

вот обычная программа.Как сделать такой же красивый запуск всплывающий и закрытие?пж ссылку или пример)очень п
Буду благодарен)

Дайте ссылку
Дайте кто-нибудь ссылку на форму, где можна задать вопрос админам googla, если таковая имеется.


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита табличной части. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru