Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.06.2012, 01:42   #11
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

То есть если у меня есть класс, в котором конструктор при создании добавляет к а единицу, мне надо использовать new.
А если мне надо выделить память под динамический массив int - malloc?
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 05.06.2012, 01:50   #12
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Нет, new подходит для всех типов. malloc - функция из С, new - оператор из C++.
Да и new просто удобнее и читабельнее. Сравните:
Код:
int * a = new int [n];
int * b = (int *)malloc(n * sizeof(int));
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 05.06.2012, 10:59   #13
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

я спокойно могу использовать new во всех случаях?
спасибо!
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 05.06.2012, 12:23   #14
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в С++ да во всех.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.06.2012, 13:14   #15
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Удалять не забывай.
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 05.06.2012, 15:12   #16
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Цитата:
Сообщение от Blind Guard Посмотреть сообщение
1) Допустим в файле f используется строка str
Формулировка непонятна. Есть такие понятия, как "буфер" и "содержимое буфера". Будем называть строкой содержимое буфера.

Чтобы считать строку из файла нужно иметь выделенный буфер.

Буфер можно выделить двумя способами:

1) Статическое выделение памяти:
Код:
#include <stdio.h>

#define BSIZE 20

int main()
{
    char buf[BSIZE];

    return 0;
}
2) Динамическое выделение памяти:
Код:
#include <stdio.h>
#include <stdlib.h>

#define BSIZE 20

int main()
{
    char *buf;

    buf = (char *) malloc(BSIZE);

    free(buf);
    return 0;
}
Цитата:
Сообщение от Blind Guard Посмотреть сообщение
Так вот, нужно ли выделять память под эту строку каждый раз после очередного открытия файла или достаточно одного выделения памяти?
Открытие файла никак несвязанно с буфером. В буфер мы можем записывать данные из файла или считывать из буфера данные в файл.

Пример считывание из файла в буфер, который выделен динамически:

infile.txt
Цитата:
hello, world!
Код:
#include <stdio.h>
#include <stdlib.h>

#define BSIZE 20

int main()
{
    char *buf;

    char *filename = "infile.txt";
    FILE *fp = fopen(filename, "r");

    if (fp == NULL) {
        fprintf(stderr, "Error: cannot open file \"%s\"\n", filename);
        return 1;
    }

    buf = (char *) malloc(BSIZE);

    fgets(buf, BSIZE, fp);

    free(buf);
    fclose(fp);
    return 0;
}
Динамическое выделение памяти нужно, чтобы при необходимости можно было увеличить буфер. Статический буфер увеличить не получится. А динамический можно сделать неограниченно большим (ограничение - размер оперативной памяти).

К примеру, мы считываем данные из файла в буфер, чтобы обработать. Допустим, что количество данных в файле - нам неизвестно. Количество данных может быть - 3 однобайтовых числа. А может быть 5 миллиардом чисел (однобайтовых). Скажем, у нас оперативной памяти 4Г байт.

Как быть? Есть два варианта решения:
1) с динамической памятью;
2) без динамической памяти.

Нужно учесть, что буфер выделенный статически "раздувает" исполняемый (exe-файла) ровно на свой размер. А динамический буфер "не раздувает" exe-файл. Динамический буфер "раздувается" в оперативной памяти (exe-файл остаётся прежним).

Вот как можно поступать с динамической памятью:
1) выделить небольшой кусочек (скажем 100 байт);
2) заполнить этот буфер;
3) если данные в файле остались, то нужно выделить ещё:
Цитата:
новый_размер_буфера = старый_размер_буфера + 100 байт
.
И копировать всё содержимое старого буфера в новый.

Ну конечно, ненужно забывать, что размер оперативной памяти конечен. Поэтому нужно задать ограничительное число. Если размер буфера станет больше этого числа, то нужно приступить к обработке данных. Обработать данные. Освободить буфер. Затем, снова выделить буфер размером 100 байт и т.д.

А статический буфер конечен, поэтому после его заполнения нужно обработать данные. Затем опять заполнить буфер.

Цитата:
Сообщение от Blind Guard Посмотреть сообщение
2) Допустим строка str задействована и в функции и вне её в main'е.
Необходимо ли выделять память в функции? (то есть будет ли память, выделенная под строку перед функцией распространяться на эту же строку, но уже в функции)?
Ненужно. К примеру, вы выделяете динамически буфер в main. Передаёте в функцию func адрес начала буфера и его размер:

Код:
func(buf, BSIZE);
Если вам буфер уже не нужен (после возврата из функции func), то вы этот буфер освобождаете с помощью функции free(buf).

Цитата:
Сообщение от Blind Guard Посмотреть сообщение
3) Скажется ли как-нибудь выделение памяти под один и тот же элемент несколько раз?
Конечно скажется! Это называется "утечка памяти". Имеется ввиду, что если выделять многократно динамически память (и не освобождать её). То может наступить момент, что вся оперативная память закончится. И те приложения, которым понадобится оперативная память, аварийно завершатся. Честно говоря я не знаю, как это будет выглядеть. Надо бы эксперимент провести как-нибудь. Но вам не советую так делать. Может у операционной системы есть какая-то защита.

Цитата:
Сообщение от Blind Guard Посмотреть сообщение
4) Допустим есть строка str и функция func(). Чтобы избежать постоянного выделения памяти можно ли сделать функцию выделения памяти, то есть при входе в func() str без памяти, а после выхода под str уже будет выделена память? (только ради уменьшения длины кода )
Так делать нельзя. func может выделить внутри себя память и она же обязана её освободить. Либо main выделяет память и передаёт в func адрес начала буфера и его размер. И main освобождает буфер.

Последний раз редактировалось 8Observer8; 05.06.2012 в 15:24.
8Observer8 вне форума Ответить с цитированием
Старый 05.06.2012, 15:13   #17
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

У меня по ходу дела возникло два вопроса:
1) Может ли func освободить буфер?
Код:
#include <stdio.h>
#include <stdlib.h>

#define BSIZE 100

void func(char *);

int main()
{
    char *buf;

    buf = (char *) malloc(BSIZE);

    free(buf);

    return 0;
}

void func(char *b)
{
    free(b);
    return;
}
2) Почему после освобождения буфера мы всё ещё можем туда писать?
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BSIZE 100

int main()
{
    char *buf;

    buf = (char *) malloc(BSIZE);

    free(buf);

    strcpy(buf, "hello, world!");

    return 0;
}
8Observer8 вне форума Ответить с цитированием
Старый 05.06.2012, 16:03   #18
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Нужно учесть, что буфер выделенный статически "раздувает" исполняемый (exe-файла) ровно на свой размер.
читаем про .bss
Цитата:
Может ли func освободить буфер?
может, но такой подход не очень.
Цитата:
Почему после освобождения буфера мы всё ещё можем туда писать?
потому что у вас есть указатель.
потому что страница в которую вы пишете еще не освобождена.
но это есть повреждение кучи.
далее там могут оказаться иные данные, которую будут испорчены.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.06.2012, 16:42   #19
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Пепел Феникса, благодарю!
8Observer8 вне форума Ответить с цитированием
Старый 05.06.2012, 20:11   #20
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от 8Observer8 Посмотреть сообщение
Буфер можно выделить двумя способами:
Если ограничиться лишь рамками с++, то к твоим услугам три класса памяти: динамика, статика, стек.

Цитата:
Сообщение от 8Observer8 Посмотреть сообщение

1) Статическое выделение памяти:
Код:
#include <stdio.h>

#define BSIZE 20

int main()
{
    char buf[BSIZE]; //стек
    return 0;
}
Ты ошибаешься. В этом примере память была выделена на стеке.

Вот пример статического массива:

Код:
#define BSIZE 20

char buf[BSIZE]; //статическая область памяти
int main()
{
    return 0;
}
Что бы в туловище функции объявить статические данные, необходимо явно указать класс памяти:

Код:
#define BSIZE 20

int main()
{
    static char buf[BSIZE]; //статическая область памяти
    return 0;
}
В самом бинарнике есть инструкция о том, как следует инициализировать статические данные при запуске процесса, но не сами данные. Поэтому, раздувания размера бинарного файла из-за обилия статических данных не происходит.

Пример:

Код:
#define BSIZE 20

char buf[BSIZE]; //статическая область памяти
int main()
{
    return 0;
}
По стандарту должен быть заполнен нулями.

Нет ни одной причины хранить в бинарнике все 20 обнуленных элементов.
Достаточно сохранить лишь количество. Итак понятно, что все они при запуске должны быть заполнены нулями.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Распределение памяти. Динамическое выделение памяти с++ Tolian92 Помощь студентам 8 14.05.2012 21:44
Выделение памяти (new) ImmortalAlexSan Общие вопросы C/C++ 20 05.06.2011 23:39
Выделение памяти в С++ Dj-IIyIIc Общие вопросы C/C++ 4 18.10.2010 14:39
выделение памяти Артем1256 Общие вопросы C/C++ 1 13.11.2009 16:38
Выделение памяти mutabor Общие вопросы Delphi 8 26.08.2009 18:16