Динамическая память под массивы (C)

Модератор: Модераторы разделов

BratSinot
Сообщения: 812
ОС: Slackware64

Динамическая память под массивы

Сообщение BratSinot »

Здравствуйте! Возник такой вопрос: А можно удалять отдельные элементы массива? Поясняю:
Допустим у нас есть массив:

Код: Выделить всё

double tmp[10];

Я выделил динамическую память под этот массив. Я хочу убрать из памяти элемент массива 5, но чтоб нумерация сохранялась.
Можно ли это сделать стандартными силами C, или надо извращаться?

И в догонку, что будет если переменной типа int, выделить один байт информации?
Спасибо сказали:
MrSinister
Сообщения: 95

Re: Динамическая память под массивы

Сообщение MrSinister »

BratSinot писал(а):
05.05.2010 21:55
Здравствуйте! Возник такой вопрос: А можно удалять отдельные элементы массива? Поясняю:
Допустим у нас есть массив:

Код: Выделить всё

double tmp[10];

Я выделил динамическую память под этот массив. Я хочу убрать из памяти элемент массива 5, но чтоб нумерация сохранялась.
Можно ли это сделать стандартными силами C, или надо извращаться?

И в догонку, что будет если переменной типа int, выделить один байт информации?

Насколько я знаю, наврядли у тебя такое получится. Тут даже realloc не поможет. Как он будет нумерацию сохранять, если там ничего нет. Другое дело, если ты сделаешь массив указателей на элементы. типа double **tmp; tmp = (double**) calloc(10, sizeof(double*)); Потом выделить память под каждый элемент, и тогда ты сможешь освобождать память каждого элемента. free (tmp[5]);
Ну или можно использовать динамические структуры, списки там всякие и т.д :)

BratSinot писал(а):
05.05.2010 21:55
И в догонку, что будет если переменной типа int, выделить один байт информации?

Проверил бы сам) Вот такое будет:

Код: Выделить всё

#include <stdio.h>
int main() {
    int *ic;
    ic = (int*) malloc (sizeof(char));
    ic = 'f';
    printf("%c  %d\n", ic, sizeof(ic));
    free(ic);
    return 0;
}

Код: Выделить всё

[mrsinister@cybertron ~]$ gcc -g -o testt testt.c
testt.c: In function ‘main’:
testt.c:5: warning: incompatible implicit declaration of built-in function ‘malloc’
testt.c:6: warning: assignment makes pointer from integer without a cast
testt.c:8: warning: incompatible implicit declaration of built-in function ‘free’
[mrsinister@cybertron ~]$ ./testt
f  8
Segmentation fault (core dumped)


Код:

Breakpoint 1 at 0x40055c: file testt.c, line 5. (gdb) run Starting program: /home/mrsinister/testt Breakpoint 1, main () at testt.c:5 5 ic = (int*) malloc (sizeof(char)); (gdb) print ic $1 = (int *) 0x0 (gdb) next 6 ic = 'f'; (gdb) print ic $4 = (int *) 0x601010 (gdb) print *ic $5 = 0 (gdb) next 7 printf("%c %d\n", ic, sizeof(ic)); (gdb) print ic $7 = (int *) 0x66 (gdb) print *ic Cannot access memory at address 0x66 (gdb) next f 8 8 free(ic); (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7adfcdc in free () from /lib64/libc.so.6 (gdb) quit


Это может доставить проблем, конечно)
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Динамическая память под массивы

Сообщение eddy »

Чтобы не перемещать туда-сюда весь массив, ИМХО, в этом случае есть только одно решение - связанные списки:

Код: Выделить всё

struct thedata{
double data;
struct tmp* prev;
struct tmp* next;
};

Тогда будет проще вставить элемент в любое место "массива" и удалить его.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
AestheteAnimus
Сообщения: 135
ОС: FreeBSD 8.0-RELEASE amd64

Re: Динамическая память под массивы

Сообщение AestheteAnimus »

BratSinot писал(а):
05.05.2010 21:55
Я выделил динамическую память под этот массив. Я хочу убрать из памяти элемент массива 5, но чтоб нумерация сохранялась.
Можно ли это сделать стандартными силами C, или надо извращаться?

Для начала нужно понять, что массивов как таковых в Си нет, есть только куски памяти. Поэтому задача "убрать из памяти элемент", вообще говоря, некорректна. Еще более бессмысленно сохранение нумерации в массиве при удалении элемента - получите довольно громоздскую и сравнительно медленную конструкцию (скорее всего, это будет словарь по ключу int), без которой, скорее всего, можно было бы обойтись. Поэтому, сперва объясните, что у Вас за задача, приводящая к столь странным решениям. А так, "стандартными средствами Си" можно сделать все что угодно :yes3:



BratSinot писал(а):
05.05.2010 21:55
И в догонку, что будет если переменной типа int, выделить один байт информации?

Пф... Разыменовываете Вы все равно sizeof(int) байт. Так что, будете читать и затирать память, которая, возможно, уже кому-то принадлежит.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

BratSinot писал(а):
05.05.2010 21:55
Здравствуйте! Возник такой вопрос: А можно удалять отдельные элементы массива? Поясняю:
Допустим у нас есть массив:

Код: Выделить всё

double tmp[10];

Я выделил динамическую память под этот массив. Я хочу убрать из памяти элемент массива 5, но чтоб нумерация сохранялась.
Можно ли это сделать стандартными силами C, или надо извращаться?

И в догонку, что будет если переменной типа int, выделить один байт информации?
Вам ещё в предыдущей теме объяснили, что ничего хорошего не будет. Вообще, стоит менять либо подходы, либо язык.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Динамическая память под массивы

Сообщение Crazy »

BratSinot писал(а):
05.05.2010 21:55
Здравствуйте! Возник такой вопрос: А можно удалять отдельные элементы массива? Поясняю:
Допустим у нас есть массив:

Код: Выделить всё

double tmp[10];

Я выделил динамическую память под этот массив. Я хочу убрать из памяти элемент массива 5, но чтоб нумерация сохранялась.
Можно ли это сделать стандартными силами C, или надо извращаться?

И в догонку, что будет если переменной типа int, выделить один байт информации?

По определению массива нет.

Desipere in loco
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Динамическая память под массивы

Сообщение BratSinot »

t.t писал(а):
10.05.2010 16:23
Вам ещё в предыдущей теме объяснили, что ничего хорошего не будет. Вообще, стоит менять либо подходы, либо язык.

Мне это не для программы надо, а так для интереса.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Динамическая память под массивы

Сообщение drBatty »

BratSinot писал(а):
05.05.2010 21:55
Здравствуйте! Возник такой вопрос: А можно удалять отдельные элементы массива? Поясняю:
Допустим у нас есть массив:
Код
double tmp[10];

Я выделил динамическую память под этот массив. Я хочу убрать из памяти элемент массива 5, но чтоб нумерация сохранялась.
Можно ли это сделать стандартными силами C, или надо извращаться?

как уже выше сказано - вопрос не имеет смысла. во всяком случае, стандартные средства си на это не способны. вы можете использовать C++, перезагрузив operator[], либо используя STL (ЕМНИП там что-то такое было).
BratSinot писал(а):
05.05.2010 21:55
И в догонку, что будет если переменной типа int, выделить один байт информации?

этот вопрос так-же не имеет смысла, по той причине, что выделением памяти занимается компилятор, и вас никто спрашивать об этом не будет. Известно-лишь то, что тип int занимает не меньше, чем тип char (понятие "байт" вообще не определено в С). конкретный размер определяется реализацией, обычно - 4 байта. если вы выделите 1 байт(точнее 1 char), то запишется туда всё равно 4. нравится вам это, или нет.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Динамическая память под массивы

Сообщение eddy »

drBatty писал(а):
10.05.2010 17:16
если вы выделите 1 байт(точнее 1 char), то запишется туда всё равно 4. нравится вам это, или нет.

Почему же, можно сделать сегфолт при помощи конструкции

Код: Выделить всё

char x;
int *ptr = (int*)&x;
*ptr=1; // Segfault

или так:

Код: Выделить всё

int *ptr = calloc(1, 1);
*ptr = 1; // Segfault
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

drBatty писал(а):
10.05.2010 17:16
конкретный размер определяется реализацией, обычно - 4 байта.
Правильнее будет сказать: обычно он равен разрядности архитектуры. На 32-битных системах обычно 4 байта. На 16-битных -- обычно 2. На 8-битных -- почти всегда 1. Но последние -- уже точно история; так что вероятность получить однобайтный int на современном железе без специальных ухищрений очень близка к нулю.

Автору темы: когда int одному байту не равен, то такой фокус гарантировано приведёт Вашу программу к чему-нибудь нехорошему. В лучшем случае к непредсказуемым значениям переменных; в наиболее частом случае к сегфолту.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Динамическая память под массивы

Сообщение BratSinot »

drBatty писал(а):
10.05.2010 17:16
этот вопрос так-же не имеет смысла, по той причине, что выделением памяти занимается компилятор, и вас никто спрашивать об этом не будет.

ДА? А sizeof то-же компилятор указывает?
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Динамическая память под массивы

Сообщение eddy »

BratSinot писал(а):
10.05.2010 18:19
А sizeof тоже компилятор указывает?

sizeof - обычный макрос компилятора.
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
Red User
Сообщения: 229
ОС: Debian

Re: Динамическая память под массивы

Сообщение Red User »

eddy писал(а):
10.05.2010 18:25
sizeof - обычный макрос компилятора.

Это не макрос, это операция.
А ведь когда-то не боялись мы программы любой,
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

Red User писал(а):
10.05.2010 18:33
eddy писал(а):
10.05.2010 18:25
sizeof - обычный макрос компилятора.
Это не макрос, это операция.
Строго говоря, фраза "макрос компилятора" вообще лишена смысла, т.к. раскрытием макросов занимается препроцессор, и компилятор уже о них не знает.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Динамическая память под массивы

Сообщение drBatty »

eddy писал(а):
10.05.2010 17:25
Почему же, можно сделать сегфолт при помощи конструкции

в данном случае это не понравится самой ОС.
t.t писал(а):
10.05.2010 18:10
Автору темы: когда int одному байту не равен, то такой фокус гарантировано приведёт Вашу программу к чему-нибудь нехорошему.

когда равен - тоже. сменится CPU и всё - программу можно будет выкинуть в помойку.
BratSinot писал(а):
10.05.2010 18:19
ДА? А sizeof то-же компилятор указывает?

конечно. sizeof это ключевое свойство компилятора, которое тождественно равно размеру объекта в char'ах. часто char равен байту, и потому sizeof "возвращает" размер в байтах. в кавычках потому, что вообще-говоря, sizeof это константа, потому запись sizeof(int) полностью эквивалентна записи 4 (в случае, что в данной архитектуре данный компилятор считает, что int - 4х байтовый, а char - однобайтовый). потому sizeof похож на макросы, хотя макросом и не является (т.к. обрабатывается уже после обработки макросов, о чём выше уже писали)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

drBatty писал(а):
10.05.2010 19:44
t.t писал(а):
10.05.2010 18:10
Автору темы: когда int одному байту не равен, то такой фокус гарантировано приведёт Вашу программу к чему-нибудь нехорошему.
когда равен - тоже. сменится CPU и всё - программу можно будет выкинуть в помойку.
Совершенно верно. Впрочем, если из моих слов казалось, что я поощряю равноценное использование int и char даже в программах, которые гарантировано будут работать только на восьмибитных машинах, значит я неверно выразился. Это в любом случае порочная практика.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Динамическая память под массивы

Сообщение BratSinot »

eddy писал(а):
10.05.2010 18:25
sizeof - обычный макрос компилятора.

Ёпрст! Я про то, что malloc я указываю сколько байт выделить.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

BratSinot писал(а):
10.05.2010 20:43
eddy писал(а):
10.05.2010 18:25
sizeof - обычный макрос компилятора.
Ёпрст! Я про то, что malloc я указываю сколько байт выделить.
Не байт, а char-ов, Вам на это уже указали.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Red User
Сообщения: 229
ОС: Debian

Re: Динамическая память под массивы

Сообщение Red User »

t.t писал(а):
10.05.2010 21:02
Не байт, а char-ов, Вам на это уже указали.

Вообще, если посмотреть в спецификацию C99, то там говорится, что sizeof возвращает число байт. Правда, число битов в байте не определено и считается зависящим от реализации.
А ведь когда-то не боялись мы программы любой,
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Динамическая память под массивы

Сообщение drBatty »

Red User писал(а):
10.05.2010 21:12
Вообще, если посмотреть в спецификацию C99, то там говорится, что sizeof возвращает число байт. Правда, число битов в байте не определено и считается зависящим от реализации.

ну это всё слова - в самом языке никаких байтов никогда не было, в отличие от char'ов. (:
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

Red User писал(а):
10.05.2010 21:12
t.t писал(а):
10.05.2010 21:02
Не байт, а char-ов, Вам на это уже указали.
Вообще, если посмотреть в спецификацию C99, то там говорится, что sizeof возвращает число байт. Правда, число битов в байте не определено и считается зависящим от реализации.
Именно из-за этой оговорки мне кажется не совсем корректным оперировать здесь понятием "байт" в повседневной жизни: времена машин (и так довольно редких) с байтом другой длины давно прошли, и сейчас слово "байт" однозначно воспринимается как синоним фразы "восемь бит".
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Динамическая память под массивы

Сообщение drBatty »

BratSinot писал(а):
10.05.2010 20:43
Ёпрст! Я про то, что malloc я указываю сколько байт выделить.

вы не байты указываете - есть особый тип, size_t, и именно в этих попугаях и принимает размер malloc(), и то-же отдаёт и sizeof. обычно в одном этом попугае 1 байт, но не всегда. ЕМНИП раньше было что 1 size_t тождественно равен 1 char'у, а сейчас - не в курсе. Может уже и не так...

t.t писал(а):
10.05.2010 21:29
времена машин (и так довольно редких) с байтом другой длины давно прошли, и сейчас слово "байт" однозначно воспринимается как синоним фразы "восемь бит".

ну кто знает - вполне возможно, что скоро в байте будет 16 бит. например моя мобила так и считает, когда русские смски отправляет..
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

drBatty писал(а):
10.05.2010 21:34
t.t писал(а):
10.05.2010 21:29
времена машин (и так довольно редких) с байтом другой длины давно прошли, и сейчас слово "байт" однозначно воспринимается как синоним фразы "восемь бит".
ну кто знает - вполне возможно, что скоро в байте будет 16 бит. например моя мобила так и считает, когда русские смски отправляет..
Мобилка с чувством юмора -- это здорово. (: А если серьёзно, то кроме разработчиков таких интересных девайсов и программ, думаю, никто в обозримом будущем так считать не будет.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Red User
Сообщения: 229
ОС: Debian

Re: Динамическая память под массивы

Сообщение Red User »

drBatty писал(а):
10.05.2010 21:34
вы не байты указываете - есть особый тип, size_t, и именно в этих попугаях и принимает размер malloc(), и то-же отдаёт и sizeof.
Вы путаете тип данных и единицу измерения.
А ведь когда-то не боялись мы программы любой,
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Динамическая память под массивы

Сообщение drBatty »

t.t писал(а):
10.05.2010 21:49
Мобилка с чувством юмора -- это здорово. (: А если серьёзно, то кроме разработчиков таких интересных девайсов и программ, думаю, никто в обозримом будущем так считать не будет.

я тоже надеюсь...
Red User писал(а):
10.05.2010 21:50
вы не байты указываете - есть особый тип, size_t, и именно в этих попугаях и принимает размер malloc(), и то-же отдаёт и sizeof.

Вы путаете тип данных и единицу измерения.

и в чём тут принципиальная разница? особенно в контексте "сколько байтов в int"? size_t это не только тип, но и единица измерения, именно в этих единицах malloc (и прочие функции) определяют количество информации.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Red User
Сообщения: 229
ОС: Debian

Re: Динамическая память под массивы

Сообщение Red User »

drBatty писал(а):
10.05.2010 22:50
size_t это не только тип, но и единица измерения, именно в этих единицах malloc (и прочие функции) определяют количество информации.

size_t - это только тип. Например, malloc считает, что size_t - это размер чего-то в байтах (одна единица измерения), а size_t wcslen(const wchar_t *s) возвращает длину строки в символах wchar_t (другая единица измерения).
А ведь когда-то не боялись мы программы любой,
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Динамическая память под массивы

Сообщение drBatty »

Red User писал(а):
10.05.2010 23:12
size_t wcslen(const wchar_t *s) возвращает длину строки в символах wchar_t (другая единица измерения).

ну это особый случай. эта функция должна возвращать безразмерную величину. вот она и возвращает "просто число". а вот sizeof возвращает размер, и не важно, что кодеры уже не представляют, что у размера тоже есть единица измерения (ну да, на многих системах она тождественна равна единице).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Динамическая память под массивы

Сообщение BratSinot »

Red User писал(а):
10.05.2010 21:12
Вообще, если посмотреть в спецификацию C99, то там говорится, что sizeof возвращает число байт. Правда, число битов в байте не определено и считается зависящим от реализации.

Вы того? В байте 8 бит и это не от компилятора зависит! Просто в оперативке нельзя зарезервировать меньше байта, поэтому всякие _Bool и bool при резервировании занимают 1Байт, а не 1Бит.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Динамическая память под массивы

Сообщение t.t »

BratSinot писал(а):
11.05.2010 07:20
Red User писал(а):
10.05.2010 21:12
Вообще, если посмотреть в спецификацию C99, то там говорится, что sizeof возвращает число байт. Правда, число битов в байте не определено и считается зависящим от реализации.
Вы того?
Выбирайте выражения, пожалуйста. Люди Вам же помочь хотят.

BratSinot писал(а):
11.05.2010 07:20
В байте 8 бит и это не от компилятора зависит! Просто в оперативке нельзя зарезервировать меньше байта, поэтому всякие _Bool и bool при резервировании занимают 1Байт, а не 1Бит.
Вы сначала указанную спецификацию почитайте, а потом спорьте.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Динамическая память под массивы

Сообщение eddy »

BratSinot писал(а):
11.05.2010 07:20
В байте 8 бит и это не от компилятора зависит!

Вы, наверное, удивитесь, но в байте некоторых контроллеров 12, 14 и даже 16 бит :)
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали: