Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
#1

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

10.02.2011, 13:55. Просмотров 1215. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2011, 13:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Дайте ссылку или пример на интересующий меня вопрос. (C++):

Дайте ссылку на Dshow - C++
Помогите! Киньте мне силку на dshow.a, никак не могу найти

Дайте ссылку на компилятор C++ - C++
Здравствуйте дайте ссылку на компилятор C++ пожалуйста!

MVC дайте пример - C++
Столько прочитал книг и статей про этот шаблон,прочитал так же про другие шаблоны GoF...все понимаю,а применить не могу:confused: Все...

Дайте пожалуйста ссылку на сайт с командами - C++
Помогите вспомнить на сайт с командами и функциями для С++, точно не помню на кажется эта страница была на сайте Microsoft, но что то не...

Где найти borland С++, дайте ссылку - C++
Я студент, задали курсач по информатике, программу нужно писать в borland С++. Нигде не могу ее найти, скиньте пожалуйста или ссылку или...

Дайте ссылку, где можно разобраться с табуляцией? - C++
привет. В учебнике только сказано, что 2 символа\t означают табуляцию. погуглил: аналогичная ситуация, в найденных источниках только пишут,...

20
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
10.02.2011, 14:06 #2
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
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 14:15  [ТС] #3
За пример спасибо.
Цитата Сообщение от alex_x_x Посмотреть сообщение
можно и на указателях все, но лень было править
А можно хотябы на словах как это все должно происходить при использовании указателей или где почитать.
0
alex_x_x
бжни
2450 / 1655 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
10.02.2011, 14:27 #4
почитайте про утечки памяти
например
http://www.cyberguru.ru/programming/...mory-leak.html
http://cppworld.h16.ru/stdc/memory.htm
http://www.amse.ru/courses/cpp1/2009.10.19.html
http://www.intuit.ru/department/algorithms/staldata/27/

здесь надо понимать уровень на котором ведется разговор
первоначально важно понимать как правильно работать с указателями, когда можно и нужно их освобождать
далее идут вопросы как не нужно работать с указателями, когда не нужно, смарт поинтеры и так далее
определитесь с общими понятиями в них даются общие правила работы
1
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 14:37 #5
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
easybudda
Модератор
Эксперт CЭксперт С++
9693 / 5643 / 962
Регистрация: 25.07.2009
Сообщений: 10,847
10.02.2011, 14:38 #6
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
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 15:20  [ТС] #7
Цитата Сообщение от talis Посмотреть сообщение
Указатель-то вы объявили, а сам массив не создали.
В функции ReadBuffer я и создавал сам массив
Buffer = new FRAGMENT[x];

В принципе программа нормально работала, пока я незахотел с помощю этой функции инициализировать еще один массив.
Тогда то я и понял что абсолютно ничего непонимаю и не только с операторами new и delete.
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 15:30 #8
Да, действительно. Извините. Просто сбивает с толку
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
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:09  [ТС] #9
Давайте начну сначала, я попробую расказать чего я хочу добиться от своей программы.
Допустим есть консольное приложение с большим буфером экрана (назовем ее плоскостью А). Я создаю дополнительную плоскость тоже большого размера, назовем ее Б. Чтобы скопировать с плоскости Б на плоскость А определенный прямоугольник символов с их атрибуми использую функции 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
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:12  [ТС] #10
Навсякий случай прикреплю програмку, так будет более понятно. Она работает, только на чсном слове.
0
Вложения
Тип файла: rar main_control.rar (2.6 Кб, 18 просмотров)
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:15  [ТС] #11
Цитата Сообщение от easybudda Посмотреть сообщение
если хотите сохранять в файл массив структур, лучше в структуре поле char *lpBuffer; сделать не указателем, а массивом
Дело в том что я незнаю в определенный момент размер этого массива. Он вычисляется по ходу работы.
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 16:19 #12
QWAN, 64 Кб * 1024 = 65536 байт. Вы действительно думаете, что вам не хватит?

Добавлено через 17 секунд
Попробую вникнуть в вашу проблему...
0
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 16:29  [ТС] #13
Цитата Сообщение от talis Посмотреть сообщение
64 Кб * 1024 = 65536 байт. Вы действительно думаете, что вам не хватит?
Максимум что у меня получилось скопировать (по памяти) это прямоугольник 140 * 95. хотя он и немного меньше чем 64К. Причину я так и неустановил.
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.02.2011, 17:07 #14
Посмотрел я вашу программу. Вам удалось записать прямоугольник в 400 байт. Это действительно немного меньше 64 килобайт
Существенные корректировки пометил как MY_EDIT: в комментарии. Решении проблем с вылетом пометил как SOLUTION:
Вообще, пол-программы пришлось перелопатить. Если что - спрашивайте.
1
Вложения
Тип файла: zip main.zip (3.2 Кб, 14 просмотров)
QWAN
58 / 57 / 1
Регистрация: 02.09.2008
Сообщений: 181
10.02.2011, 18:36  [ТС] #15
Спасибо, за переделанную програмку. Пока только смотрю что переделали. Вопросы чуть позже напишу, когда более вникну.
Цитата Сообщение от 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
10.02.2011, 18:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.02.2011, 18:36
Привет! Вот еще темы с ответами:

дайте пожалуйста ссылку где скачать Turbo С++ - C++
дайте пожалуйста ссылку где скачать Turbo С++

Дайте пожалуйста рабочий пример регулярного выражения c++ - C++
Мне нужно что-то типа AnsiString regexp = /&lt;b&gt;(.*)&lt;\/b&gt;/i; AnsiString str = &quot;&lt;b&gt;Hello World!&lt;/b&gt;&quot;; preg_match(str, pegexp, result); ...

Интерфейсы в с++ дайте кто нибудь годный рабочий пример - C++
Суть вопроса: нигде не могу найти рабочий пример использования интерфейсов, то есть когда есть интерфес, есть класс внутри длл-ки и всё это...

У меня вопрос - C++
Почему прога не вычисляет максимальный и минимальный элемент в матрице? Пишет не так Код вроде бы верен, а толку от этого нет ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru