Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
1

Каков механизм выделения битов под участок памяти

04.07.2014, 11:49. Просмотров 698. Ответов 18
Метки нет (Все метки)

Кто нибудь знает механику выделения битов под участок памяти?

Суть в чем:
  1. Объявил функцию, в ней забрал кусок динамической памяти, вышел из функции, отдал "вверх" ссылку на адрес этого участка. (статики не объявляю, автоматические переменные все схлопнулись).
  2. Зашел в другу функцию, получил в фактически в стек копию той ссылки, играюсь с ней (инкрементируя саму ссылку, уходя в середину участка) копию полученной ссылки умышленно не объявлял.
Хочу узнать сколько осталось позиций между тем участком на котором я сейчас нахожусь и концом динамического куска, возможно так?

Есть такая удобная функция, memset, скармливая ей ссылку на текущую позицию в участке (как я понял, не обязательно адрес начала), она может обнулить участок. Откуда ей известен конец участка? Есть какой-то признак конца участка или данная функция забирает инфу от windows-планировщика памяти?

Окружение: мастдайка 8, visual studio 12
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.07.2014, 11:49
Ответы с готовыми решениями:

Ошибка выделения памяти под массив
Есть двумерный массив. Создается он таким образом: int **createArray(int m, int n) { int i,...

Приведите свой вариант оптимального выделения памяти под 2 матрицы
В коде надо выделить память под 2 матрицы. Возникло несколько вопросов: 1)Там где память...

Распределение памяти для выделения и освобождения блоков памяти внутри запрошенного пула
В программе малые"дыры" избегают,что нужно сделать что бы малые "дыры" не избегались.... #...

Динамическое выделения памяти под массив
Доброе утро. Прошу помощи! Была программа на С++, переделывал на С#, и столкнулся с такой...

Отличие выделения адресатов памяти под vector
Почему при исполнении программы первая ячейка отличается от следующих. И почему не заполняются...

18
HighPredator
5697 / 2018 / 723
Регистрация: 10.12.2010
Сообщений: 5,794
Записей в блоге: 3
04.07.2014, 11:56 2
Цитата Сообщение от lightfrag Посмотреть сообщение
Откуда ей известен конец участка?
Это третий параметр.

Добавлено через 1 минуту
А основную часть вопроса не понял вообще.
1
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
04.07.2014, 11:59  [ТС] 3
p.s. есть неудобный способ, который пользуюсь - делаю копию ссылки начала участка, и в глобальных переменных храню - количество ед. всего участка. (( *уч.начала + праращ_ед_всего) - (*тек.участок)) / sizeof(ТИП).
p.p.s прав ли я что sizeof(тип) != sizeof(*нач.участка) , ведь второе возвращает размер байт ссылки а не хранимого объекта?

Добавлено через 2 минуты
Цитата Сообщение от HighPredator Посмотреть сообщение
Это третий параметр.
C
1
2
3
4
void func (char **ptr){
  memset(ptr, 0, sizeof(ptr));
  return;
}
т.е. хочешь сказать он мне чистит не весь участок а только 1 элемент? если писать вот так.
0
HighPredator
5697 / 2018 / 723
Регистрация: 10.12.2010
Сообщений: 5,794
Записей в блоге: 3
04.07.2014, 12:02 4
ptr у вас что? Указатель. sizeof от чего? Указателя. Соответственно размер чего будет возвращен? Указателя.
1
04.07.2014, 12:02
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
04.07.2014, 12:15  [ТС] 5
Открыл файл, хочу прочитать его в динамический массив,
прошу памяти, на количество элементов файла.

bLetterCounter - текущее кол-во элементов в файле.

C
1
2
3
4
5
6
7
8
9
10
char **DataPREHandler(register FILE **cF){
 
  static char *cTxtBuff;
...
 
  if (!(cTxtBuff = (char *)calloc(sizeof(char), (size_t)bLetterCounter)))
    return NULL;
 
...
  return cTxtBuff
далее грубо говоря делаю word wrap, раздвигая массив и вставляя перенос строк,
когда нахожу строку длиннее заданного числа ухожу в функцию описанную ниже

cBuffer - начало массива, curCBuff - текущее положение для вставки '\n'

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
static int buffMovForward(char *cBuffer, const char *curCBuff){
    
        //если при раздвигании, окажется что дальняя граница больше объема выделенной памяти
    if (bLetterCounter + 1lu > mySizeOf(cBuffer))
        myRealloc(&cBuffer);
 
        //увеличиваю кол-во символов и приращиваю на их количество начало массива
    cBuffer += ++bLetterCounter;
    
    do{
        *cBuffer = *(cBuffer - 1);
        --cBuffer;
    } while (cBuffer > curCBuff);
 
    *cBuffer = '\n';
 
        //если я довел счетчик до места сдвига то все ок
    return cBuffer == curCBuff ? DONE : ERROR;
}
 
 
long unsigned mySizeOf(char *cBuff){
 
        //#define SIZE(object)  sizeof(*object)/sizeof(object[0])
    return SIZE(cBuff);
}
0
HighPredator
5697 / 2018 / 723
Регистрация: 10.12.2010
Сообщений: 5,794
Записей в блоге: 3
04.07.2014, 12:17 6
Рад за вас. Вопрос-то в чем?
1
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
04.07.2014, 12:23  [ТС] 7
у меня размер памяти чуть-чуть больше чем кол-во символов в массиве (*(bLetterCounter + cBuffer) != конец куска памяти) , и я проверяю что при очередной вставке не выйду за его границы.

А функция mySizeOf , в таком описании, возвращает всегда 1, соотв. я всегда сваливаюсь на функцию увеличения массива. Можно как то узнать реальный текущий размер памяти, не храня его не в глобальных, ни передавая в функцию?
0
HighPredator
5697 / 2018 / 723
Регистрация: 10.12.2010
Сообщений: 5,794
Записей в блоге: 3
04.07.2014, 12:28 8
Во, вот такой вопрос я понял. Чувствуете разницу между этим и вашими предыдущими постами? Ответ: без хаков - нет.
0
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
04.07.2014, 12:51  [ТС] 9
Есть две идеи, обе мутные:
1. Флажок. Устанавливать вконец участка символ который не будет встречаться в ASCII.
2. (гипотетически). Библиотека assert.h, никогда не пользовался, но из моих скудных java-знаний, нельзя выход эксепшеном проверять?
0
HighPredator
5697 / 2018 / 723
Регистрация: 10.12.2010
Сообщений: 5,794
Записей в блоге: 3
04.07.2014, 13:31 10
Обе идеи плохие. Передавайте размер как параметр.
0
castorsky
1973 / 1076 / 87
Регистрация: 29.11.2013
Сообщений: 3,354
04.07.2014, 14:49 11
Цитата Сообщение от lightfrag Посмотреть сообщение
А функция mySizeOf , в таком описании, возвращает всегда 1
C
1
#define SIZE(object)  sizeof(object)/sizeof(object[0])
Цитата Сообщение от lightfrag Посмотреть сообщение
у меня размер памяти чуть-чуть больше чем кол-во символов в массиве
При выделении памяти заполняете ее всю нулями (memset/bzero)
C
1
2
3
#ifndef HAVE_BZERO
#define bero(ptr, nmemb) (memset(ptr, 0, nmemb))
#endif
После этого для вычисления длины буфера можно использовать strlen/strnlen. Однако, поскольку Вы имеете возможность всегда контролировать длину буфера, то можно ее просто хранить в памяти и изменять в случае необходимости.

Добавлено через 4 минуты
Ну и пример Вашего макроса
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ cat shit.c && gcc shit.c && ./a.out 
#include <stdio.h>
#include <stdlib.h>
 
#define SIZE(object)  sizeof(object)/sizeof(object[0])
 
int
main (int argc, char ** argv)
{
    int a[10];
    int * b = malloc(40);
    int c = SIZE(a);
    int d = SIZE(b);
    
    fprintf(stdout, "%d, %d\n", c, d);
    
    exit(EXIT_SUCCESS);
}
10, 2
0
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
04.07.2014, 15:56  [ТС] 12
Цитата Сообщение от castorsky Посмотреть сообщение
При выделении памяти заполняете ее всю нулями (memset/bzero)
В начале темы, выше, есть вырезки кода, в которых говорится об использовании calloc, при первоначальном выделении места.

Изменяется объем хранимых данных, приходится делать так (да, мб, не оптимизировано, но рефакторинг дело 2-е)

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char **myRealloc(char **cTextBuffer){
 
    char * tmpCTB;
 
    if ((tmpCTB = (char *)calloc(sizeof(char), (size_t)(bLetterCounter + 1lu))) != NULL) {
        memcpy(tmpCTB, *cTextBuffer, (size_t)bLetterCounter * sizeof(char));
 
        (int)tmpCTB ^= (int)*cTextBuffer;
        (int)*cTextBuffer ^= (int)tmpCTB;
        (int)tmpCTB ^= (int)*cTextBuffer;
 
        free(tmpCTB);
    }
 
    return cTextBuffer;
}
Цитата Сообщение от castorsky Посмотреть сообщение
Ну и пример Вашего макроса
Это тоже известно, вопрос в другом - почему если ссылка константа(а именно таковыми являются объявленные штатными средствами массивы) размер sizeof(arr)/sizeof(arr[0]) получить можно, а если адрес на массив - то нет.


Цитата Сообщение от castorsky Посмотреть сообщение
При выделении памяти заполняете ее всю нулями (memset/bzero)
За bzero спасибо, не знал, интересно.
0
HighPredator
5697 / 2018 / 723
Регистрация: 10.12.2010
Сообщений: 5,794
Записей в блоге: 3
04.07.2014, 16:06 13
Цитата Сообщение от lightfrag Посмотреть сообщение
ссылка константа
Бррр. Уберите пожалуйста термин "ссылка" из лексики. В си нет ссылок. Поэтому я не могу допереть, что вы подчас имеете ввиду.
0
lightfrag
1 / 1 / 2
Регистрация: 19.07.2013
Сообщений: 35
04.07.2014, 16:14  [ТС] 14
Цитата Сообщение от castorsky Посмотреть сообщение
После этого для вычисления длины буфера можно использовать strlen/strnlen
Менять всякий раз размер памяти при небольших изменениях в данных, дело затратное.
Кроме того случается непонятная !%№ при отладке - Например:
- я знаю что после данной функции мой дин. массив увеличится на N, я realloc-ом увеличиваю его, а после увеличения у меня на брейкпоинте в массиве показывает N+12 непонятных знаков приписанных Х3 откуда.
По этому realloc-для меня не выход
0
castorsky
1973 / 1076 / 87
Регистрация: 29.11.2013
Сообщений: 3,354
04.07.2014, 20:10 15
Лучший ответ Сообщение было отмечено lightfrag как решение

Решение

Цитата Сообщение от lightfrag Посмотреть сообщение
По этому realloc-для меня не выход
Да блин, я не понимаю что Вам мешает после каждого копирования данных запилить ноль в конец массива по индексу?
Цитата Сообщение от lightfrag Посмотреть сообщение
приходится делать так
Честно говоря я не понимаю смысл этой пляски, зачем "ехать в Париж через Рио"?
C
1
2
3
4
5
6
7
8
9
10
11
12
char **myRealloc(char **cTextBuffer){
 
    char * tmpCTB;
 
    if ((tmpCTB = (char *)calloc(sizeof(char), (size_t)(bLetterCounter + 1lu))) != NULL) {
        memcpy(tmpCTB, *cTextBuffer, (size_t)bLetterCounter * sizeof(char)); 
 
        free(*cTextBuffer);
        *cTextBuffer = tmpCTB;
    } 
    return cTextBuffer;
}
Цитата Сообщение от lightfrag Посмотреть сообщение
Это тоже известно, вопрос в другом - почему если ссылка константа(а именно таковыми являются объявленные штатными средствами массивы) размер sizeof(arr)/sizeof(arr[0]) получить можно, а если адрес на массив - то нет.
Ссылок тут нет. Ответ: Реальные адреса динамической памяти "разбросаны" по всем страницам, которые доступны процессу для хранения данных. Реальные адреса статических массивов линейны.
1
korvin_
2405 / 1882 / 341
Регистрация: 28.04.2012
Сообщений: 6,477
04.07.2014, 23:39 16
Цитата Сообщение от castorsky Посмотреть сообщение
C
1
#define SIZE(object) *sizeof(object)/sizeof(object[0])
И какой практический смысл?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
#define SIZE(object)  sizeof(object)/sizeof(object[0])
 
void
ololo(char *s)
{
    printf("size = %d\n", SIZE(s));
    printf("data = %s\n", s);
}
 
int
main(void)
{
    ololo("foobar");
    return 0;
}
Bash
1
2
size = 4
data = foobar
0
castorsky
1973 / 1076 / 87
Регистрация: 29.11.2013
Сообщений: 3,354
05.07.2014, 11:09 17
korvin_, не понимаю вопроса. Я такие макросы никогда не использую. Это для школьников, чтобы лабораторные работы сдавать. Я же говорю что размеры буферов должны храниться отдельно, по возможности в RO памяти.
0
Vtulhu
425 / 379 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
06.07.2014, 10:30 18
Я не очень понял вопроса, но есть смутная надежда, что готовый менеджер памяти спасет отца русской демократии.

Вот, например, BOEHM. Зацените список проектов, использующих его - http://www.hboehm.info/gc/#users

И не надо такие вещи велосипедить, люди их вылизывали годами, а Вы сделаете в лучшем случае глючное и убогое подмножество возможностей, которые Вам дают на блюдечке с голубой каемочкой. Кончается это всегда плохо.
0
SatanaXIII
Почетный модератор
Эксперт С++
5796 / 2791 / 385
Регистрация: 01.11.2011
Сообщений: 6,797
Завершенные тесты: 1
08.07.2014, 15:47 19
Цитата Сообщение от castorsky Посмотреть сообщение
При выделении памяти заполняете ее всю нулями
Может быть calloc просто использовать?
0
08.07.2014, 15:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2014, 15:47

Что значат эти строки выделения памяти под массив символов?
что значат эти строки? я так понимаю это значит что выделяется память на 20 символов и если будет...

Можно ли изменить размерность массива после выделения памяти под него?
Можно ли изменить размерность массива после выделения памяти под него?

Каков механизм отладки программ ASP?
Каков механизм отладки программ ASP? Чтобы посмотреть, что ты напрограммировал надо все кинуть в...


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

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

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