שלום לכולם,
מישהו שהיה.יודע מה שואלים. מישהו מכיר את החברה? ...
תודה מראש
ע"י: מהנדסון
אפשר גם כך:
unsigned int num = 16;
binary_num *binNum = (binary_num *)# // use the binary_num from above
printf("bit 4's value: %d", binNum->bit_4;
אפשר לקבל הסבר איך מתבצעת ההמרה?
ע"י: 1_אורח_כללי
אפשר גם כך:
unsigned int num = 16;
binary_num *binNum = (binary_num *)# // use the binary_num from above
printf("bit 4's value: %d", binNum->bit_4;
ע"י: תכנת-סיפיפי
היי,
פשוט תשתמש ב union
union select
{
binary_num n;
unsigned int i;
};
union select u;
u.i = i;
printf ("decimal :%lu ",u.i);
printf("0b%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d
%d\n",...);
ע"י: 1_אורח_כללי
מישהו יכול להסביר איך מבצעים את ה cast הנ"ל?
כשאני מנסה לעשות cast רגיל ל int הקומפיילר צועק עלי...
ע"י: תכנת-סיפיפי
אני חושב שהתשובה הופיע פה בפורום פעם, מדובר ב cast למבנה שמכיל bit-field
typedef struct
{
unsigned int bit_1 :1;
unsigned int bit_2 :1;
unsigned int bit_3 :1;
unsigned int bit_4 :1;
unsigned int bit_5 :1;
unsigned int bit_6 :1;
unsigned int bit_7 :1;
unsigned int bit_8 :1;
unsigned int bit_9 :1;
unsigned int bit_10 :1;
unsigned int bit_11 :1;
unsigned int bit_12 :1;
unsigned int bit_13 :1;
unsigned int bit_14 :1;
unsigned int bit_15 :1;
unsigned int bit_16 :1;
unsigned int bit_17 :1;
unsigned int bit_18 :1;
unsigned int bit_19 :1;
unsigned int bit_20 :1;
unsigned int bit_21 :1;
unsigned int bit_22 :1;
unsigned int bit_23 :1;
unsigned int bit_24 :1;
unsigned int bit_25 :1;
unsigned int bit_26 :1;
unsigned int bit_27 :1;
unsigned int bit_28 :1;
unsigned int bit_29 :1;
unsigned int bit_30 :1;
unsigned int bit_31 :1;
unsigned int bit_32 :1;
} binary_num;
במקרה של המרה כזו כמובן שצריך לדעת/לגלות את ה endianess של המעבד ולפיו לסדר את הביטים
ע"י: 1_אורח_כללי
אני חושב שהתשובה הופיע פה בפורום פעם, מדובר ב cast למבנה שמכיל bit-field
typedef struct
{
unsigned int bit_1 :1;
unsigned int bit_2 :1;
unsigned int bit_3 :1;
unsigned int bit_4 :1;
unsigned int bit_5 :1;
unsigned int bit_6 :1;
unsigned int bit_7 :1;
unsigned int bit_8 :1;
unsigned int bit_9 :1;
unsigned int bit_10 :1;
unsigned int bit_11 :1;
unsigned int bit_12 :1;
unsigned int bit_13 :1;
unsigned int bit_14 :1;
unsigned int bit_15 :1;
unsigned int bit_16 :1;
unsigned int bit_17 :1;
unsigned int bit_18 :1;
unsigned int bit_19 :1;
unsigned int bit_20 :1;
unsigned int bit_21 :1;
unsigned int bit_22 :1;
unsigned int bit_23 :1;
unsigned int bit_24 :1;
unsigned int bit_25 :1;
unsigned int bit_26 :1;
unsigned int bit_27 :1;
unsigned int bit_28 :1;
unsigned int bit_29 :1;
unsigned int bit_30 :1;
unsigned int bit_31 :1;
unsigned int bit_32 :1;
} binary_num;
במקרה של המרה כזו כמובן שצריך לדעת/לגלות את ה endianess של המעבד ולפיו לסדר את הביטים
מה זה המבנה הזה??? הוא קיים?? אתה יכול להסביר איך ניגשים לזה??
ע"י: 1_אורח_כללי
על מה אתה מדבר? איזה דרך אלגנטית יותר מחלוקה/shift
אולי תפרט...
ע"י: תכנת-סיפיפי
למען האמת מערכת ניהול הזיכרון שהראית היא דיי בסיסית ולדעתי יש בה סוג של משקל עודף שיכול להיות מוקש בראיון (המערךבו אתה שומר את הכתובות ששוחררו) אני מניח שמצפים שתנהל ת הכתובות ששוחררו באותו מבנה הנתונים שהוקצת למען מערכת ה pool
משהו כמו זה
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include "prick.h"
#define POOL_SIZE 1024
typedef struct
{
unsigned int next:31;
unsigned int available:1;
} available_brick;
static unsigned char pool[sizeof(mem_brick)*POOL_SIZE]={0};
static pthread_mutex_t _s_pool_mutex;
typedef struct
{
void* available;
volatile size_t size;
unsigned char initilaized;
unsigned char *mem_pool;
pthread_mutex_t* pool_mutex;
}pool_manager;
static pool_manager the_manager= {(void*)&pool[0],POOL_SIZE,0,&pool[0],&_s_pool_mutex};
static int init_pool()
{
unsigned int i = 0;
if (the_manager.initilaized)
{
return 1;
}
pthread_mutex_lock(the_manager.pool_mutex);
if (the_manager.initilaized)
{
pthread_mutex_unlock(the_manager.pool_mutex);
return 1;
}
available_brick *ab = (available_brick*) (&the_manager.mem_pool[0]);
for (;i < 1024 ; )
{
ab->available = 1;
ab->next= (unsigned short)++i;
}
the_manager.initilaized =1;
pthread_mutex_unlock(the_manager.pool_mutex);
return 1;
}
mem_brick* allocate_brick()
{
static int initilaized = 0;
mem_brick *ret;
initilaized = (initilaized == 0)?init_pool():initilaized;
if (the_manager.size == 0 && the_manager.available == the_manager.mem_pool+1025)
{
return NULL; /*nothing available*/
}
pthread_mutex_lock(the_manager.pool_mutex);
available_brick *ab= (available_brick*)the_manager.available;
--the_manager.size;
the_manager.available = the_manager.mem_pool + ab->next;
ab->available = 0;
pthread_mutex_unlock(the_manager.pool_mutex);
return (mem_brick*)(ab);
}
void free_brick(mem_brick *p)
{
assert (p >= (mem_brick*)the_manager.mem_pool && p <= (mem_brick*)the_manager.mem_pool+1024);
available_brick *ab= (available_brick*) p;
assert (ab->available==0);
pthread_mutex_lock(the_manager.pool_mutex);
++the_manager.size;
ab->next = (unsigned short)((void*)the_manager.available-(void*)the_manager.mem_pool);
the_manager.available=(void*)ab;
pthread_mutex_unlock(the_manager.pool_mutex);
}
ועוד משהו לגבי ההמרה לבינרי, זה משהו שאני נתקלתי בו די הרבה, וחשבתי לעצמי שבעצם המידה ב=כבר מצוי בזיכרון אז למה בעצם צריך לבצע shift בלולאה כדי להגיע לתשובה.
אני מצאתי דרך שלטעמי לפחות ניראית יותר אלגנטית.
ע"י: 1_אורח_כללי
אם הבנתי נכון, אתה אומר שזה בזבזני להחזיק טבלה בגדול 32^2 ועדיף להחזיק טבלה קטנה יותר
ולהשתמש ב- DOUBLE HASHING. צודק.
ע"י: האקר_מצוי
תשובה לאורח
נכון מקרה קלאסי של post increment.
לגבי IP, שימוש רציף במרחב הזיכרון של int32 עלול להיות בזבזני ומטרת הhash לנסות לספק גישה (במצב אופטימלי) ב (1)O
אני מניח שהתקלות עם IP מסוים היא אקראית ולא ניתקל בכול מספרי IP. כדי למנוע מצבים של הצעות כפולות אני חושב שאין די בפונקצית HASH בדידה ואולי יש כאן מקום ל double-hashing.
ע"י: 1_אורח_כללי
בקשר ל-ip-hash, למה לא לשמור כ-int32? הרי מדובר ב- sizeof(char)*4 ?
אשמח להסבר
ע"י: 1_אורח_כללי
שאלת תם (בהחלט יתכן שאני טועה):
יכול להיות שהתכוונת ל-++wild_pricks_iter במקום wild_pricks_iter++ ?
כי נראה שכך אתה תמיד מדלג על האיבר הראשון ולא מכניס בו כלום...
ע"י: האקר_מצוי
המשך לפוסט הקודם...
ip-hash אני לא ממש בטוח, לדעתי קשה למצוא צירוף יחד מוצלח של פונקציית HASH אני מני כי מדובר ב IPV4 לכן אולי הייתי משתשמש ב CRC32 או איזה אלגוריתם כריפטוגרפי אחר.
לגבי מבנה הנתונים המבוקש נראה לי
#include <unordered_map>
//forward decl
class ip_pm;
class ip_stats;
typedef unorderd_map<ip_pm> ip_pm_hash;
typedef unordered_map<ip_stats> ip_stats_hash;
class ip_stats
{
private:
size_t tx_;
size_t rx_;
};
class ip_pm
{
private:
ip_stats_hash ip_stats_;
};
ע"י: האקר_מצוי
תודה,
לגבי השאלה הראשונה, חשבתי על הפיתרון הבא:
קובץ prick.h
typedef struct
{
unsigned int value;
} prick;
prick* allocate_prick();
void free_prick(prick* p);
קובץ prick_pool.c
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include "prick.h"
#define POOL_SIZE 100
static unsigned char pool[sizeof(prick)*POOL_SIZE]={0};
static unsigned char* pool_iter= pool;
static prick* wild_pricks[POOL_SIZE]={0};
static prick** wild_pricks_iter= wild_pricks;
static unsigned char check_realloc_hash[POOL_SIZE]={1};
static pthread_mutex_t free_mutex;
static pthread_mutex_t pool_mutex;
unsigned char hash_pointer(prick* p)
{
unsigned char ret = (unsigned char)(p - (prick*)&pool[0]);
assert (ret < 100);
return ret;
}
prick* allocate_prick()
{
prick* ret;
pthread_mutex_lock(&free_mutex);
if (wild_pricks_iter > wild_pricks)
{
ret=*wild_pricks_iter;
check_realloc_hash[hash_pointer(*wild_pricks_iter)] = 1;
--wild_pricks_iter;
pthread_mutex_unlock(&free_mutex);
return ret;
}
pthread_mutex_unlock(&free_mutex);
/* no one has been deallocated */
pthread_mutex_lock(&pool_mutex);
if (pool_iter == pool+sizeof(prick)*POOL_SIZE)
{
ret = (prick*)0;
}
else
{
ret= (prick*)pool_iter;
pool_iter+= sizeof(prick);
}
pthread_mutex_unlock(&pool_mutex);
return ret;
}
void free_prick(prick* p)
{
pthread_mutex_lock(&free_mutex);
if (check_realloc_hash[hash_pointer(p)] == 0)
{
printf("prick pointer p 0x%x has been already freed\n",p);
pthread_mutex_unlock(&free_mutex);
return;
}
check_realloc_hash[hash_pointer(p)] = 0;
*(++wild_pricks_iter)= p;
pthread_mutex_unlock(&free_mutex);
}
לא חשבתי על דרך לצמצם את הנעילות!
משמעות שיחרור כפול בד"כ לא מוגדרת אך מובילה להשחתת מערכת ניהול הזיכרון
המרה לתצוגה בינרית ע"י אופרטור shift
int main(int argc,char** argv)
{
unsigned long num= 125;
unsigned long input;
if (argc ==2)
{
sscanf(argv[1],"%lu",&num);
}
input = num;
const int buff_size = sizeof(unsigned long)*8;
char res[buff_size +1] = {0};
int start = buff_size-1;
for(int i=0; i< buff_size || num ;++i)
{
start = (num & 1)? (buff_size -1 -i):start;
res [buff_size-i-1] = (num & 1)?'1':'0';
num >>= 1;
}
printf (" size is %d, start is %d\n",sizeof(unsigned long), start);
printf ("input in dec is %lu in binary is %s\n",input,&res[start]);
return 0;
}
מה דעתכם?
ע"י: 1_אורח_כללי
שלום האקר,
אני לא יודע מה התפקיד שהוצע לך, התחום שלהם הוא בעיקר בתחום ip-filter ברמת NAT אירגוני.
הקידוד הוא ב C ואם לשפוט לפי מכרים שעבדו שם, אין יותר מדי מקום לדימיון מפותח.
השאלות שכך לפחות סיפרו לי הם:
לתכנן מערכת להקצאת זיכרון לגודל מבנה נתונים(struct) ידוע לדוגמה 8 בתים, המערכת מוגבלת לסה"כ אלמנטים מוקצים ואין הוספה מעבר לאיתחול הראשוני. הגישה להקצאה היא MT.
יש לכתוב את פונקציות malloc ו free תוך מינימום נעילות אם בכלל.
משמעות שיחרור כפול בזמן ריצה? להוסיף ב free בדיקה למניעת שיחרור כפול.
לכתוב פונקציה שמדפיסה מספר בבינרית.
איזה HASH יהיה יעיל לאחסון כתובות ip, לבנות מבנה נתונים ששומר סטטיסטיקות משלוח וקבלה של packets ממוין לפי שולח.נמען לכול ip.