LINUX.ORG.RU

Передача структуры в функцию на Си


0

1
struct watch {
    struct in_addr ipaddress; // remote ip
    int port; //remote port
    char *pathname; //file to be watched
};
typedef struct watch watch_t;

// file change handler will be called 
// when an event happens
// with parameters: watch details and the 
// event that occurred  on that watch
typedef void (*filechangehandler_t)(watch_t, int); << -- передаем структуру

Почему этот код не дает ошибку? Ведь передается не указатель на структуру, а - структура. Разве такое разрешено в Си?

★★★★★

Ответ на: комментарий от LamerOk

> Частично ошибаешься. enum появился в С, причем очень рано, задолго до страуса с крестами.

Точно, ошибся.

anonymous
()
Ответ на: комментарий от Eddy_Em

> Я вообще предпочитаю с массивами не связываться. Если уж надо область памяти выделить, я предпочитаю malloc/calloc.

malloc/calloc несут с собой проблемы управления динамической памятью, поэтому если есть возможность использовать автоматическую память ей надо пользоваться.

И вот лучше, если вычислений времени компиляции будет поменьше.

Предлагаете все вычисления в рантайме выполнять?

anonymous
()
Ответ на: комментарий от anonymous

Не, похоже прибрехнул я. В другой книге это читал (про оптимизацию кода).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Предлагаете все вычисления в рантайме выполнять?

Конечно. Для препроцессора надо оставлять лишь контекстно-зависимые параметры. Скажем, число ядер процессора для определения количества потоков при распараллеливании вычислений; расположение файла с переводом для gettext'а; параметры отладки и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

> malloc/calloc несут с собой проблемы управления динамической памятью, поэтому если есть возможность использовать автоматическую память ей надо пользоваться.


Использовать надо и то, и то, просто для разных целей. В системах, отличных от популярных дистрибутивов GNU/Linux с настройками по умолчанию, выставлено ограничение на размер стека, с тем, чтобы процесс ушедший в бесконечную рекурсию не помешал жить остальным.

Кроме того у malloc/calloc есть одно важное преимущество - возможность более легко обработать ошибку выделения памяти.

LamerOk ★★★★★
()
Ответ на: комментарий от Eddy_Em

Боюсь, вы не поняли вопроса. Почему так получается, что приложение на C или C++ в среднем будет быстрее работать, чем на Java?

V_L_A_D ★★
()
Ответ на: комментарий от V_L_A_D

> Почему так получается, что приложение на C или C++ в

среднем будет быстрее работать, чем на Java?


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

anonymous
()
Ответ на: комментарий от V_L_A_D

Потому что программа на С/С++ и прочем компилируемом под родную архитектуру ЯП выполняется, так сказать, непосредственно CPU, без посредников. А всякие явы и моны выполняются на посреднике - виртуальной машине.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Потому что программа на С/С++ и прочем компилируемом под родную архитектуру ЯП выполняется, так сказать, непосредственно CPU, без посредников. А всякие явы и моны выполняются на посреднике - виртуальной машине.

само по себе это не гарантирует повышения производительности. создание объекта в Java дешевле, чем в C++; создание потока/переключение контекста в Erlang/Haskell дешевле, чем в C++/pthreads

jtootf ★★★★★
()
Ответ на: комментарий от Eddy_Em

>>Предлагаете все вычисления в рантайме выполнять?

Конечно.

Вот ты странный. С одной стороны, пишешь на языке со статической типизацией, в котором масса работы вополняется во время компиляции. С другой тсороны, твердишь, что все вычисления нужно делать в рантайме. Ну и какие плюшки ты хочешь получить от «низкоуровневого С», если он будет тормозить хуже явы?

staseg ★★★★★
()
Ответ на: комментарий от staseg

в котором масса работы вополняется во время компиляции

Какая же там работа выполняется во время компиляции?

И как я могу выделять мега/гигабайты оперативки на этапе компиляции? =)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от jtootf

само по себе это не гарантирует повышения производительности. создание объекта в Java дешевле, чем в C++; создание потока/переключение контекста в Erlang/Haskell дешевле, чем в C++/pthreads

евгений ваганый пелогинтесь и расскажите это жабло софту который постоянно тормозит и жрет все ресурсы

anonymous
()
Ответ на: комментарий от LamerOk

> Кроме того у malloc/calloc есть одно важное преимущество - возможность более легко обработать ошибку выделения памяти.

В этом вашем линуксе malloc никогда не вернёт NULL при нехватке памяти и если к тому моменту, как произодёт обращение к «выделенному» куску памяти он будет всё ещё занят, ядро прибьёт процесс с SIGSEGV. Так что обработка ошибок malloc в линуксе вообще теряет смысл.

anonymous
()
Ответ на: комментарий от Eddy_Em

>Потому что программа на С/С++ и прочем компилируемом под родную архитектуру ЯП выполняется, так сказать, непосредственно CPU, без посредников. А всякие явы и моны выполняются на посреднике - виртуальной машине.
http://www.linux.org.ru/jump-message.jsp?msgid=6240525&cid=6244420
java сравнима с компилированным gcc с -march=native кодом и быстрее, чем просто -O2 на моём железе.

x3al ★★★★★
()
Ответ на: комментарий от x3al

[quote}Java тормозит? А вот и нет! :) (комментарий) java сравнима с компилированным gcc с -march=native кодом и быстрее, чем просто -O2 на моём железе. [/quote} сын евгения ваганыча? или внук? не надо сравнивать коней в сферических комнатах без ваккума

anonymous
()
Ответ на: комментарий от Eddy_Em

>Какая же там работа выполняется во время компиляции?

Типизация (тут много работы и, грубо говоря, оптимизаций последующих вывычислений в рантайме), расположение данных в статической памяти, расчет того, как укладывать данные в стек, оптимизации, отсечение участков кода, которые не будут выполняться, вычисление выражений, состоящих из констант. Зачем все это выносить в рантайм?

И как я могу выделять мега/гигабайты оперативки на этапе компиляции?

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

staseg ★★★★★
()
Ответ на: комментарий от anonymous

Э? Там измеряется скорость CPU. Внезапно получается, что java не медленнее компилированного под конкретный процессор кода (и быстрее компилированного под абстрактный). То есть VM тормозит в других местах.

x3al ★★★★★
()
Ответ на: комментарий от anonymous

Маны почитать не бывает?

On error, these functions return NULL.

Если malloc не сможет выделить достаточно памяти, он вернет NULL. Т.е. проверив указатель после malloc'а можно сказать: была память выделена, или нет.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от staseg

Понятно. Но это - не вычисления, это лишь оптимизация. Сами вычисления вы никак не сможете отдать препроцессору.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от x3al

Э? Там измеряется скорость CPU. Внезапно получается, что java не медленнее компилированного под конкретный процессор кода (и быстрее компилированного под абстрактный). То есть VM тормозит в других местах.

да шовы говорите )), а почему там нет сравнения скорости присваивания a = b; или a = 5; вы еще пля сравните по времени жабовское выделения памяти которое уже заранее резервирует жаба машина, и с/c++ malloc

anonymous
()
Ответ на: комментарий от Eddy_Em

> Если malloc не сможет выделить достаточно памяти, он вернет NULL. Т.е. проверив указатель после malloc'а можно сказать: была память выделена, или нет.

Маны почитать не бывает?

Попробуйте прочитать ман про malloc от корки до корки.

anonymous
()
Ответ на: комментарий от anonymous

И что? Всего 2 страницы на calloc, malloc, free и realloc. В секции RETURN VALUE все отлично расписано. В секции NOTES упомянуто, что «шухер» бывает при нарушении кучи и двойном free. В общем, ничего такого, говорящего, что malloc может не выделив заказанной области памяти вернуть не-NULL.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> Если malloc не сможет выделить достаточно памяти, он вернет NULL. Т.е. проверив указатель после malloc'а можно сказать: была память выделена, или нет.

посмотри, что вернёт malloc на просьбу выделить в два раза больше памяти, чем у тебя её есть (включая своп, конечно).

arsi ★★★★★
()
Ответ на: комментарий от Eddy_Em

> В общем, ничего такого, говорящего, что malloc может не выделив заказанной области памяти вернуть не-NULL.

Может все-таки до самого конца дочитаете?

anonymous
()
Ответ на: комментарий от Eddy_Em

> А как malloc'у больше 2ГБ передать?

А в чем собственно сложность?

anonymous
()
Ответ на: комментарий от Eddy_Em

> On error, these functions return NULL.

В том же мане в разделе BUGS читаем:

By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is __no guarantee__ that the memory really is available. This is a really bad bug.

anonymous
()
Ответ на: комментарий от anonymous

Ладно, убедили :)

А как malloc'у больше 2ГБ передать?

А в чем собственно сложность?

Сложность в том, что у malloc'а по умолчанию аргумент имеет тип size_t, а эта собака 32-битная. Специально проверял - при указании size_t x = 5000000000LL на самом деле x принимает совершенно другое значение.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

В том же мане в разделе BUGS читаем:

> By default, Linux follows an optimistic memory allocation strategy. This means that when malloc() returns non-NULL there is __no guarantee__ that the memory really is available. This is a really bad bug.


И при чём тут Linux? Линукс - это всего лишь ядро.

LamerOk ★★★★★
()
Ответ на: комментарий от Eddy_Em

> Сложность в том, что у malloc'а по умолчанию аргумент имеет тип size_t, а эта собака 32-битная.

Это от платформы зависит.

А как malloc'у больше 2ГБ передать?

В чем магичность 2Гб?

Специально проверял - при указании size_t x = 5000000000LL на самом деле x принимает совершенно другое значение.

Зачем сразу 5000000000LL? 3Гб как бы тоже больше 2Гб.

anonymous
()
Ответ на: комментарий от anonymous

В чем магичность 2Гб?

В том, что это - максимальное число, которое можно передать 32-битным int'ом, коим и является size_t =)

3Гб как бы тоже больше 2Гб.

У меня 2ГБ оперативки + 2ГБ свопа. Так что, надо точно больше 4ГБ.

И да, система, как сами понимаете, 32-битная (вот куплю еще гигов 6 оперативки, поставлю 64-битную).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> больше 2ГБ

Сложность в том, что у malloc'а по умолчанию аргумент имеет тип size_t, а эта собака 32-битная.

«size_t is an unsigned data type»

aho
()
Ответ на: комментарий от aho

Точно, sorry.

Ладно. Вот пример: пытаюсь выделить 4ГБ оперативки:

19:28 /dev/shm
cat 1.c 
#include <stdlib.h>
#include <stdio.h>
main(){
	size_t s = 4000000000UL;
	printf("sizeof s = %d, s = %lu\n", sizeof(s), s);
	char *ptr = malloc(s);
	if(ptr) printf("OK\n");
	else printf("NO\n");
}
19:27 /dev/shm
cat > 2.c
#include <stdlib.h>
#include <stdio.h>
main(){
	size_t s = 4000000000UL;
	printf("sizeof s = %d, s = %lu\n", sizeof(s), s);
	char *ptr = malloc(s);
	if(ptr) printf("OK\n");
	else printf("NO\n");
}
19:29 /dev/shm
gcc 2.c 
19:29 /dev/shm
./a.out 
sizeof s = 4, s = 4000000000
NO
Так что, матюгается...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от x3al

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

Сферические кони в вакууме приходят к финишу быстрее, чем живые (в вакууме). А вот на реальном иподроме сферические даже с места не могут сдвинутся.

anonymous
()
Ответ на: комментарий от Eddy_Em

>У меня 2ГБ оперативки + 2ГБ свопа. Так что, надо точно больше 4ГБ.
Ты не можешь заюзать >3Гб в программе (во всей, не только в этом malloc). Потому, что

32-битная


(вот куплю еще гигов 6 оперативки, поставлю 64-битную).

У меня и на одном гиге была 64-битная. Вполне сносно.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Ты не можешь заюзать >3Гб в программе (во всей, не только в этом malloc). Потому, что

32-битная

Не знал, в своих программулинках ни разу не пытался больше 2ГБ выделить.

А 64-битную пока рановато устанавливать - моя мандрива 2009 (с обновлениями) еще не настолько устарела.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Вот теперь правильно.

В этом вашем линуксе malloc никогда не вернёт NULL при нехватке памяти

Блеать, как же вы запарили с этим 4.2

Так что обработка ошибок malloc в линуксе вообще теряет смысл.

Специально для лора провожу ликбез:

anon@nymous$ ./test
1 kbib pages allocated.
2 kbib pages allocated.
3 kbib pages allocated.
...
53 kbib pages allocated.
54 kbib pages allocated.
55 kbib pages allocated.
Killed
anon@nymous$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) 1048576
file locks                      (-x) unlimited
anon@nymous$ ulimit -v 204800
anon@nymous$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) 204800
file locks                      (-x) unlimited
anon@nymous$ ./test
1 kbib pages allocated.
2 kbib pages allocated.
3 kbib pages allocated.
...
47 kbib pages allocated.
48 kbib pages allocated.
49 kbib pages allocated.
Total: 49 kbib pages allocated.
anon@nymous$ cat test.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
        char *p;
        unsigned long long count = 0;
        int i;
        int PAGE_SIZE = getpagesize();
        while (1)
        {
                p = malloc(1024*PAGE_SIZE);
                if (!p)
                {
                        printf("Total: %ld kbib pages allocated.\n", count);
                        exit(0);
                }
                for (i = 0; i < 1024; i++)
                {
                        p[PAGE_SIZE*i+PAGE_SIZE/2] = '0';
                }
                count++;
                printf("%ld kbib pages allocated.\n", count);
        }
        return 0;
}
anon@nymous$

LamerOk ★★★★★
()
Ответ на: комментарий от Eddy_Em

> пытаюсь выделить 4ГБ оперативки

ты <оскорбительное слово>? на 32-битном линухе по дефолту стоит распределение памяти 3Г/1Г, т.е. три гига адресного пространства на юзерспейс и 1 гиг — на кернелспейс. это распределение можно изменить, но только в сторону уменьшения доступного в юзерспейсе адресного пространства: 2Г/2Г или 1Г/3Г. а теперь расскажи, чем ты думал, когда пытался выделить 4 гига?

arsi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.