Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.85/20: Рейтинг темы: голосов - 20, средняя оценка - 4.85
из племени тумба-юбма
 Аватар для мама Стифлера
2523 / 1819 / 419
Регистрация: 29.11.2015
Сообщений: 8,857
Записей в блоге: 15

Выделение динамической памяти

07.10.2021, 19:05. Показов 4590. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Недавно увидел на форуме(у одного из новичков), сомнительный способ создания динамических массивов:
C
1
int *a = malloc(sizeof(int) * 5000000);
Хотя в любых учебных изданиях, включая интернет ресурсы, процесс выделения описан одинаково:
C
1
int *a = (int*)malloc(sizeof(int) * 5000000);
По началу я не придал этому никакого значения, так как вполне мог ошибиться сам студент, написавший такой код. Но вот сегодня вспомнил и решил проверить, будет ли так работать. Написал простенький код с заполнением элементов по индексам и с удивлением обнаружил, что код работает, выводит результат верно.
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
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
//  int *a = (int*)malloc(sizeof(int) * 5000000);
    int *a = malloc(sizeof(int) * 5000000);
    for(int i=0; i<5000000; i++)
        a[i] = i;
 
    int **b = malloc(sizeof(int*) * 2000);
    for(int i=0; i<2000; i++)
        b[i] = malloc(sizeof(int) * 2000);
    for(int i=0; i<2000; i++)
        for(int j=0; j<2000; j++)
            b[i][j] = i*2000+j;
 
    printf("a[%d](%d) + ", 1786247, a[1786247]);
    printf("b[%d][%d](%d)", 348, 1, b[348][1]);
    printf(" = %d\n", a[1786247]+b[348][1]);
 
    free(a);
    for(int i=0; i<2000; i++) free(b[i]);
    free(b);
    return 0;
}
Code
1
2
3
4
5
a[1786247](1786247) + b[348][1](696001) = 2482248
 
--------------------------------
Process exited after 0.3278 seconds with return value 0
Для продолжения нажмите любую клавишу . . .
Ну и для чего тогда печатать лишнее, если и без этого все работает? Буду ждать ответов в теме.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.10.2021, 19:05
Ответы с готовыми решениями:

Выделение динамической памяти
Чтобы выделить динамическую память под символьный массив надо так: int n; char *str; printf(&quot;Enter the size of the...

Выделение динамической памяти
В одномерном массиве,*состоящем из п вещественных элементов, вычислить: - минимальный элемент массива; - сумму элементов массива,...

Выделение динамической памяти в функции
В функции FromFile из файла считываю n размерность квадратной матрицы, выделяю память под матрицу и столбец, потом считываю саму матрицу и...

41
10.10.2021, 16:29
Студворк — интернет-сервис помощи студентам

Не по теме:

TheCalligrapher, для Вас пусть будет так. Лишь бы это не было как в анекдоте про комсомольцев, которые делают ЭТО в гамаке и стоя, ибо они жить не могут без трудностей. :)

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
10.10.2021, 18:18
Цитата Сообщение от CoderHuligan Посмотреть сообщение
Керниган и Ритчи - тоже?
Да, именно так.

Цитата Сообщение от CoderHuligan Посмотреть сообщение
У них пишется, что нужно явно приводить,
Одна из хорошо известных и часто приводимых в пример ошибок в книге.

История созадания второго издания известна: его в спешке вытолкнули в печать (судя по всему, по коммерческим причинам) буквально за неколько месяцев до выхода первого ANSI/ISO стандарта языка, а потом, поняв, что получилась "лажа", принялись в еще большей спешке задним числом исправлять книгу. До исправления примеров, где и можно увидеть манеру приводить результаты malloc, руки ни у кого просто не дошли. Про "нужно приводить" - как раз один из ляпов, который забыли вычистить.

Второе издание K&R - это не трэш вроде какого-нибудь Штилдта, конечно, но тем не менее это довольно низкокачественое издание - с точки зрения production.
0
из племени тумба-юбма
 Аватар для мама Стифлера
2523 / 1819 / 419
Регистрация: 29.11.2015
Сообщений: 8,857
Записей в блоге: 15
11.10.2021, 21:37  [ТС]
Короче вот книга: Язык программирования на C лекции и упражнения. Стивен Прата, вроде не старая(2015 год, 6е издание). Но один фиг, использование malloc в примерах показано в древнем виде. Ощущение, что их просто перепечатывают, возможно добавляя что то новое, а старое не редактируют совсем.
0
 Аватар для CoderHuligan
1753 / 1019 / 257
Регистрация: 30.06.2015
Сообщений: 5,132
Записей в блоге: 56
12.10.2021, 13:28
Цитата Сообщение от easybudda Посмотреть сообщение
Сами приведутся, им так по стандарту положено.
А вот сейчас заглянул в стандарт и не нашел там такого. С99.
Цитата Сообщение от мама Стифлера Посмотреть сообщение
Но один фиг, использование malloc в примерах показано в древнем виде.
Там же написано для чего: для ясности.
Цитата Сообщение от мама Стифлера Посмотреть сообщение
Назрел теперь вопрос по другому поводу из этой же темы: почему компилятор g++.exe, в отличие от gcc.exe, не понимает не приведенный тип malloc? Ведь в любом случае используются одинаковые заголовки(stdlib.h или malloc.h), в которых написано /void *malloc (size_t __size)/. Это где то еще в компиляторе заложено, или что?
Потому что это зависит целиком от компилятора, а не от стандарта. Почему возможен неявный каст? Потому что выполняется во время компиляции - компилятором. А компилятор может написать любой чел с дырой в голове, например майкрсософтовский.)) Поэтому один компилятор выдаст предупреждение, а другой нет и приведет сам, третий выдаст предупреждение и не приведет и т.д. Поэтому, чтобы ваш код был на веки вечные лучше приводить самим и не полагаться на васю пупкина с дырой в голове.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
12.10.2021, 16:24
Цитата Сообщение от CoderHuligan Посмотреть сообщение
А вот сейчас заглянул в стандарт и не нашел там такого. С99.
С99 под рукой не оказалось и искать лень, а в С11 вот, чё пишут:
A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p1
0
658 / 411 / 76
Регистрация: 21.09.2008
Сообщений: 1,412
12.10.2021, 18:28
Цитата Сообщение от easybudda Посмотреть сообщение
С99 под рукой не оказалось и искать лень
Вотъ.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
12.10.2021, 19:45
Цитата Сообщение от sharpey Посмотреть сообщение
Вотъ.
Ровно под тем же номером, практически слово в слово.
A pointer to void may be converted to or from a pointer to any incomplete or object
type. A pointer to any incomplete or object type may be converted to a pointer to void
and back again; the result shall compare equal to the original pointer.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
13.10.2021, 00:34
Лучший ответ Сообщение было отмечено CoderHuligan как решение

Решение

Цитата Сообщение от easybudda Посмотреть сообщение
http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p1
Но это - ответ "мимо кассы"!

Раздел 6.3 стандарта языка описывает семантику преобразований, когда уже известно, что преобразование будет выполняться, но 6.3 ни слова не говорит о том, когда эти преобразования будут или не будут выполняться. Это раздел никак не гарантирует, что эти преобразования будут выполняться неявно. Из того, что преобразование описано в 6.3 совсем не следует, что оно относится к допустимым неявным преобразованиям.

Об это открытым текстом написано в начале раздела

6.3 Conversions
1 Several operators convert operand values from one type to another automatically. This subclause specifies the result required from such an implicit conversion, as well as those that result from a cast operation (an explicit conversion). The list in 6.3.1.8 summarizes the conversions performed by most ordinary operators; it is supplemented as required by the discussion of each operator in 6.5.
А то так у вас и

C
1
void *p = 42;
окажется корректным С кодом только потому, что в http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p5 описано такое преобразование.

В стандарте языка С нет аналога "стандартных" (то есть неявно выполняемых) преобразований из С++. Чтобы понять, что будет, а что не будет делаться неявно, нужно лезть в описание конкретного оператора, как сказано в цитате выше.

---

Правильный ответ в данном случае надо искать именно в описании оператора присваивания (эти же правила распространяется и на инициализацию)

Сначала надо проверить ограничения простого оператора присваивания http://port70.net/~nsz/c/c11/n1570.html#6.5.16.1

Constraints
1 One of the following shall hold:
- the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
- the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
- the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
- the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.
и только когда/если мы успешно прошли через ограничения, тогда работает семантика простого оператора присваивания http://port70.net/~nsz/c/c11/n1570.html#6.5.16.1p2

Semantics
2 In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.
и только после этого, когда мы убедились в корректности кода, на сцену выходит 6.3 и описывает семантику преобразования.

Вот именно благодаря этому мы и можем присваивать void * в любой указательный тип без выполнения явного преобразования. А не благодаря 6.3. С точки зрения корректности кода 6.3 тут ни при чем вообще.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
13.10.2021, 00:58
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А то так у вас и
C
1
void *p = 42;
окажется корректным
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
"мимо кассы"
ваше замечание! Читаем внимательно:
Цитата Сообщение от easybudda Посмотреть сообщение
A pointer to void may be converted to or from a pointer to any incomplete or object
type
.
Про присвоение указателю целого (по вашей же ссылке) сказано, что такое присвоение может оказаться не корректным, т.к.
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation
Короче, снова домыслы, бестолковые примеры "мимо кассы" и вода, вода, вода... Ну чтобы желающие разобраться окончательно запутались и потерялись.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
13.10.2021, 01:53
Цитата Сообщение от easybudda Посмотреть сообщение
Читаем внимательно:
A pointer to void may be converted to or from a pointer to any incomplete or object
type.
И что? Эта фраза означает лишь то, что язык "знает" как внутренне выполняется такое преобразование (определяет семантику преобразования).

Эта фраза ни разу не означает, что вы имеете право написать в коде

C
1
2
int *p = 0;
void *v = p;
За разрешением сделать это вам нужно идти в список constraints инициализации.

Эта фраза даже не означает, что вы имеете право написать

C
1
2
int *p = 0;
void *v = (void *) p;
За разрешением сделать это вам нужно идти в список constraints явного преобразования типа

Цитата Сообщение от easybudda Посмотреть сообщение
Про присвоение указателю целого (по вашей же ссылке) сказано, что такое присвоение может оказаться не корректным, т.к.
Нет, ничего подобного там не сказано.

Под "некорректным" я имею в виду нарушения constraints: некорректный с точки зрения языка код, т.е. "некомпилируемый" код. В приведенной вам цитате (как и во всем разделе 6.3) описывается семантика процесса преобразования типов, то есть их поведение во время выполнения. Раздел 6.3 не содержит никаких constraints вообще, т.е. к корректности кода этот раздел никакого отношения не имеет никаким боком.

Как ясно написано в начале раздела 6.3 за соображениями неявной применимости преобразований нужно лезть в описания конкретных операторов. Я показал выше, что именно имеется в виду.

Цитата Сообщение от easybudda Посмотреть сообщение
Короче, снова домыслы, бестолковые примеры "мимо кассы" и вода, вода, вода... Ну чтобы желающие разобраться окончательно запутались и потерялись.
Да, грамотно и точно сформулированные объяснения - это "вода, вода, вода". Читать надо, разбираться, извилины напрягать... Зачем, правда?

Рука-лицо... Сколько усилий уже потратили на этот 6.3.. Но все как об стенку горох. Простая вроде бы тема... Кроме как нежеланием учиться я такое объяснить не могу.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
13.10.2021, 03:49
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
грамотно и точно сформулированные объяснения
Сам себя не похвалишь - весь день как оплёванный

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
"вода"
это
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А то так у вас и
и дальше то, о чём у меня и намёка не было.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Эта фраза означает лишь то, что язык "знает"
Открою страшную тайну: собственно язык программирования ничего не "знает".

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Эта фраза ни разу не означает, что вы имеете право написать в коде
И что же помешает?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
int main(void) {
    int a = 13;
    void * p = &a;
    int * pi = 0;
    void * pv = pi;
    
    
    printf("%d\n", *(int*)p);
    
    return 0;
}
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
andrew@w0721 ~/prog/winprog/c/other
$ gcc -Wall -Wpedantic ptrs.c
ptrs.c: In function ‘main’:
ptrs.c:7:9: warning: unused variable ‘pv’ [-Wunused-variable]
    7 |  void * pv = pi;
      |         ^~
 
andrew@w0721 ~/prog/winprog/c/other
$ ./a.exe
13
 
andrew@w0721 ~/prog/winprog/c/other
$
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Кроме как нежеланием учиться я такое объяснить не могу.
И не пытайтесь. Где и кого я отговаривал учиться? Только сказал Вам, что не нужно желающих разобраться пугать примерами, о которых и речи не было...
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
13.10.2021, 04:35
Цитата Сообщение от easybudda Посмотреть сообщение
Сам себя не похвалишь - весь день как оплёванный
Это ^^^, кстати, пишет оплевыватель...

Цитата Сообщение от easybudda Посмотреть сообщение
И что же помешает?
! Ничто не помешает. Кто сказал, что "помешает"? Так можно. Код корректен, разумеется.

Но речь-то идет о том, что это "можно" вытекает совсем не из 6.3. Речь идет о том, что 6.3 к "нельзя/можно" вообще никаким боком не относится. На вопросы "нельзя/можно" в языке С отвечают 1) синтаксис и 2) constraints. В разделе 6.3 нет ни слова ни о синтаксисе, ни о constraints.

Ваши инициализации корректны потому, что они удовлетворяют constraints из 6.5.16/1 (по ссылке из 6.7.9/1). Именно 6.5.16/1 говорит "можно". Я веду речь только об этом.

Цитата Сообщение от easybudda Посмотреть сообщение
не нужно желающих разобраться
Вздох... "Желающим разобраться" в качестве ответа на исходный вопрос подсовывают 6.3. ¯\_(ツ)_/¯ А потом мы по всему инету удивляемся, откуда берутся такие "разобравшиеся"...

Цитата Сообщение от easybudda Посмотреть сообщение
пугать примерами, о которых и речи не было...
Лол! Посмотрите на своей пример выше. К чему он здесь?

Вы, я вижу, совершенно не врубаетесь, о чем идет речь. И, так как в теме ничего сложного нет, данное "неврубание" я могу объяснить только нежеланием учиться.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12844 / 7593 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
13.10.2021, 11:27
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы, я вижу, совершенно не врубаетесь, о чем идет речь.
Кажется, врубился - книги надо задом на перёд читать? Я-то всегда думал, что наоборот: сначала читаем пункт 6.3 Conversions (изменение, превращение), из которого узнаём, что void* может свободно приводиться к указателю на любой другой тип и обратно, за тем смотрим, что может помешать такой метаморфозе при простом присваивании, доходим до 6.5.16.1 и сразу видим Constraints (ограничения), прочитав которые, понимаем, что ничто не мешает. А оказалось...
https://youtu.be/h0ntX3bDoOI?t=60
1
 Аватар для CoderHuligan
1753 / 1019 / 257
Регистрация: 30.06.2015
Сообщений: 5,132
Записей в блоге: 56
13.10.2021, 14:01
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
и только после этого, когда мы убедились в корректности кода, на сцену выходит 6.3 и описывает семантику преобразования.
Вот именно благодаря этому мы и можем присваивать void * в любой указательный тип без выполнения явного преобразования.
Признаю свое поражение, TheCalligrapher.
0
из племени тумба-юбма
 Аватар для мама Стифлера
2523 / 1819 / 419
Регистрация: 29.11.2015
Сообщений: 8,857
Записей в блоге: 15
13.10.2021, 14:41  [ТС]
Мне так порой кажется, что все эти стандарты языков, написаны для отельного круга людей - разработчиков. Потому, что в этих многостраничных рукописях, что то конкретно понять, могут только люди из города Зион. Для рядового программиста, вполне хватит разных справочников и вовсе не обязательно знать эти замысловатые стандарты. Хуже, или лучше от того, что прочитал программист стандарты, или не прочитал, он не станет в любом случае. И познаний не прибавится, если ничего не поймет из написанного. Главное, что нужно знать, это нововведения и изменения, пришедшие с новым стандартом.
Вот даже вполне понятный вопрос этой темы, выливается в разные недопонимания и споры, с отсылками на разные пункты стандарта. Почему в выпусках новых стандартов, нет краткой информации обо всех нововведениях и изменениях? Тогда бы не пришлось тыкать носом в разные пункты, а указать на нововведения и все.
0
 Аватар для CoderHuligan
1753 / 1019 / 257
Регистрация: 30.06.2015
Сообщений: 5,132
Записей в блоге: 56
13.10.2021, 16:40
Цитата Сообщение от мама Стифлера Посмотреть сообщение
Главное, что нужно знать, это нововведения и изменения, пришедшие с новым стандартом.
И быть уверенным, что данный компилятор поддерживает этот самый стандарт, а это не всегда бывает.
Цитата Сообщение от мама Стифлера Посмотреть сообщение
Мне так порой кажется, что все эти стандарты языков, написаны для отельного круга людей - разработчиков.
Для разработчиков компиляторов. Программистам требуются другие мануалы - справочники и учебники по языку. Керниган и Ритчи не писали стандарт, они создали Язык. Стандарт потом создали уже по факту явления. Стандарт это о том, как должен выглядеть и вести себя язык, но не факт, что этот стандарт является стандартом для разрабов конкретного компилятора.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
13.10.2021, 18:31
Цитата Сообщение от easybudda Посмотреть сообщение
Кажется, врубился - книги надо задом на перёд читать?
  • Во-первых, что такое "задом наперед"? От частного к общему? От общего к частному? А в стандарте языка так вообще перекрестных ссылок столько, что топологической сортировке это изложение не поддается.
  • Во-вторых, описание каждой фичи языка С, которую вы будете непосредственно использовать в своем коде, состоит из трех частей, расположенных локально именно в таком порядке:

    1. Синтаксис
    2. Ограничения (constraints)
    3. Семантика

    Пункты 1 и 2 определяют корректность кода (т.е. "компилируемость") и нарушение требований 1 и 2 приводит к диагностическим сообщениям ("ошибкам") на стадии компиляции. Пункт 3 описывает поведение корректного кода и нарушение требований 3 приводит к неопределенному поведению.

    Раздел 6.3 описывает именно семантику преобразований. Его вынесли в начало раздела 6, чтобы потом на него ссылаться из описаний конкретных фич языка, т.е из локальных подраздельчиков "3. Семантика" более поздних частей раздела 6. Не вижу ничего неестественного в таком порядке. Это "задом наперед" или не "задом наперед"?
  • В-третьих, стандарт языка - это reference, а не роман. И хотя на определенном уровне владения темой его действительно можно "читать" как книгу, большого смысла в этом нет. На определенном уровне владения темой "читать" стандарт можно в любом порядке.

Цитата Сообщение от easybudda Посмотреть сообщение
Я-то всегда думал, что наоборот: сначала читаем пункт 6.3 Conversions (изменение, превращение), из которого узнаём, что void* может свободно приводиться к указателю на любой другой тип и обратно
Как я уже не раз говорил выше, "может" - слишком нечеткое слово. А что вы имеете в виду под "свободно" - я вообще не понял.

Еще раз: речь в данной теме шла не о том "может ли приводиться", а о том, что "будет ли неявно приводиться", т.е. о том "разрешит ли компилятор неявное приведение". Это совершено разные вещи. Раздел 6.3 не имеет никакого отношения к разрешению и запрету именно неявных приведений. Раздел 6.3 вообще не имеет никакого отношения к разрешениям и запретам - он лишь описывает семантику.

Я уже приводил красноречивый пример выше (который вы почему-то назвали "путающим"): раздел 6.3 говорит, что целое число "может приводиться" к указательному типу. Это говорит лишь о том, что в языке С определена семантика такого приведения. Это, однако, совершенно не значит, что такое приведение будет выполняться неявно. Нет, не будет. В языке С нет неявного преобразования целого к указателю. Явное же преобразование - делайте на здоровье.

Эта путаница, т.е. необоснованное верование в то, что 6.3 якобы следует воспринимать как разрешение на неявные преобразования, в свое время была настолько распространена, что в С99 даже решили добавить 6.5.4/3

3 Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast.
Этой фразы не было в С89/90 и формально она избыточна, но ее все таки добавили ради того, чтобы окончательно "пристрелить" расхожее заблуждение о том, что 6.3 якобы следует воспринимать как разрешение на неявное выполнение всех описанных там преобразований.
0
из племени тумба-юбма
 Аватар для мама Стифлера
2523 / 1819 / 419
Регистрация: 29.11.2015
Сообщений: 8,857
Записей в блоге: 15
12.03.2023, 07:23  [ТС]
Решил вспомнить правила создания динам.массивов в С и вот увидел совет от TheCalligrapher
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Более того, лучше
C
1
int *a = malloc(sizeof *a * 5000000);
Здесь наверно ошибка закралась, а имелось ввиду так?
C
1
int *a = malloc(sizeof(a) * 5000000);
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
12.03.2023, 07:25
Цитата Сообщение от мама Стифлера Посмотреть сообщение
Решил вспомнить правила создания динам.массивов в С и вот увидел совет от TheCalligrapher

Здесь наверно ошибка закралась, а имелось ввиду так?
C
1
int *a = malloc(sizeof(a) * 5000000);
?

Нет, это у вас теперь ошибка. Правильно именно так, как изначально написано у меня.
0
из племени тумба-юбма
 Аватар для мама Стифлера
2523 / 1819 / 419
Регистрация: 29.11.2015
Сообщений: 8,857
Записей в блоге: 15
12.03.2023, 07:46  [ТС]
TheCalligrapher, ок, соглашусь.
Но ведь для оператора sizeof(), всегда указывается выражение в скобках, у вас почему без скобок и почему это правильно? Не понимаю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.03.2023, 07:46

Выделение динамической памяти внутри функции
приветствую. Изучаю С, для лушчего усвоения изобретаю велосипед - попылатся реализовать собственный вариант strcpy с использованием...

Выделение динамической памяти для массива с последующей инициализацией
Всем доброго времени суток. Собственно необходимо выделить память под динамический массив с последующей инициализацией и выводом его в...

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

Выделение динамической памяти для двумерного массива с посдедующим изменением его размера
Имеется вопрос по поводу реализации. Как это сделать без циклов и многомерных указателей, если это вообще возможно? double **d =...

Вектор, утечка памяти, функция создания и выделение памяти
Здравствуйте. Есть проблема. функция malloc выделяет память лишь в функции CreateVector(), и при выходе из нее указатель теряется. Или не...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru