קורס תכנות שיעור שמיני: הקצאת זיכרון דינאמית, הצצה לייצוג ועיבוד תמונות 1.

Slides:



Advertisements
Similar presentations
ממיבחניםC שאלות ++.
Advertisements

תוכנה 1 סמסטר א ' תשע " ב תרגול מס ' 7 * מנשקים, דיאגרמות וביטים * לא בהכרח בסדר הזה.
מבוא למדעי המחשב לתעשייה וניהול
1 Formal Specifications for Complex Systems (236368) Tutorial #4 Refinement in Z: data refinement; operations refinement; their combinations.
Agenda  Review: pointer & array  Relationship between pointer & array  Dynamic memory allocation.
הרצאה 04 הקצאות דינאמיות קרן כליף.
Pointer applications. Arrays and pointers Name of an array is a pointer constant to the first element whose value cannot be changed Address and name refer.
קורס תכנות שיעור שנים-עשר: ניהול זיכרון 1. הקצאת זיכרון דינאמית עד עכשיו עשינו "הקצאה סטטית" הגדרנו את משתני התוכנית כבר כשכתבנו אותה הקומפיילר הקצה עבורם.
הקצאות דינאמיות קרן כליף.
טבלאות סמלים נכתב ע"י אלכס קוגן סמסטר חורף, תשס"ח.
Pointers הרצאה קריטית. השאלות הפתוחות מה זה ה- & שמופיע ב scanf מדוע כשמעבירים מחרוזת ל scanf אין צורך ב & האם ניתן להכריז על מערך שגדלו אינו ידוע בתחילת.
1 מבוא למדעי המחשב הקצאה דינאמית. 2 הקצאת זיכרון דינאמית  כאשר אנו משתמשים במערכים, אנו מקצים אוטומטית את הזיכרון המקסימלי שנצטרך.  בפועל, אנו משתמשים.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
תכנות תרגול 11 שבוע : מבנים מטרת המבנים היא לאפשר למתכנת להגדיר טיפוסי משתנים חדשים אשר מתאימים ספציפית לבעיה שאותה התוכנית פותרת. מטרת המבנים.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
מבוא למדעי המחשב תרגול 8 - מחרוזות שעת קבלה : יום שני 11:00-12:00 דוא " ל :
1 Formal Specifications for Complex Systems (236368) Tutorial #5 Refinement in Z: data refinement; operations refinement; their combinations.
תוכנה 1 - חזרה שולי לב יהודי 2 Arrays and Strings מערך - אוסף משתנים בעלי שם משותף. הפנייה לכל איבר נעשית ע ” י אינדקס. ב -C מערך מוגדר.
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
תכנות תרגול 10 שבוע : הקשר בין מערכים למצביעים נרצה לעמוד על הקשר בין מערך למצביע מאחר ומערכים הם הכללה של משתנים הרי שברור שלמערך ולכל אחד מאיבריו.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
תוכנה 1 - תרגול שיעור 10 Pointers (2) שולי לב יהודי
מבוא כללי למדעי המחשב הקצאת זיכרון דינאמית
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
פוינטרים ומבנים. אתחול והדפסת מערך #include int * readArray(int size){ int *a, i; a= (int *) malloc (size* sizeof(int)); if (!a) return NULL; for (i=0;i
מבוא למדעי המחשב תרגול 12 – הקצאת זיכרון דינאמית שעת קבלה : יום שני 11:00-12:00 דוא " ל :
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
הגדרת משתנים יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר.
Dynamic Memory Allocation The process of allocating memory at run time is known as dynamic memory allocation. C does not Inherently have this facility,
מבוא למדעי המחשב הרצאה 7: מבנים מבוסס על השקפים שנערכו שי ארצי, גיתית רוקנשטיין, איתן אביאור, וסאהר אסמיר, מיכאל אלעד, רון קימל וניר אילון עדכון אחרון.
קורס תכנות שיעור עשירי: מיונים, חיפושים, וקצת סיבוכיות חישוב.
שיאון שחוריMilOSS-il מוטיבציה  python זה קל ו C זה מהיר. למה לא לשלב?  יש כבר קוד קיים ב C. אנחנו רוצים להשתמש בו, ולבסס מעליו קוד חדש ב python.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבנים קרן כליף. ביחידה זו נלמד :  מהו מבנה (struct)  איתחול מבנה  השמת מבנים  השוואת מבנים  העברת מבנה לפונקציה  מבנה בתוך מבנה  מערך של מבנים.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 6. מפעל השעווה – לולאות  עד עכשיו  טיפלנו בייצור נרות מסוג אחד, במחיר אחיד  למדנו להתמודד עם טיפול במקרים שונים.
עקרונות תכנות מונחה עצמים תרגול 11: OOP in C++. Outline  Where do the objects live ?  Inheritance  Slicing  Overriding vs Shadowing.
הגדרת משתנים יום שלישי 14 יוני 2016 יום שלישי 14 יוני 2016 יום שלישי 14 יוני 2016 יום שלישי 14 יוני 2016 יום שלישי 14 יוני 2016 יום שלישי 14 יוני 2016.
מחרוזות – הטיפוס String
Programming Arrays.
הקצאות דינאמיות בשילוב מבנים
מערכים ומצביעים הקצאה דינאמית של מערכים דו-מימדיים
שיעור חמישי: מערכים ומחרוזות
מצביעים קרן כליף.
SQL בסיסי – הגדרה אינדוקטיבית
תירגול 14: מבני נתונים דינאמיים
קורס תכנות שיעור 14: הסוף.
קורס תכנות – סמסטר ב' תשס"ח
הקצאות דינאמיות קרן כליף.
מבנים קרן כליף.
שיעור שישי: מחרוזות, מצביעים
Introduction to Programming in C
מצביעים קרן כליף.
הקצאת זיכרון דינאמית מבוא כללי למדעי המחשב
ניתוח מערכות מידע תכנות ב C#
מבוא כללי למדעי המחשב תרגול 6
סוגי משתנים קרן כליף.
מערכים של מצביעים הקצאה דינאמית
Programming in C תרגול Introduction to C - Fall Amir Menczel.
מבוא למדעי המחשב מצביעים.
תירגול 8:מצביעים והקצאה דינאמית
Computer Programming תרגול 3 Summer 2016
Engineering Programming A
Presentation transcript:

קורס תכנות שיעור שמיני: הקצאת זיכרון דינאמית, הצצה לייצוג ועיבוד תמונות 1

מבנים - Structures טיפוס חדש "חבילה" של משתנה אחד או יותר תחת שם יחיד יכול להכיל משתנים מטיפוסי שונים טיפוסים בסיסיים, מערכים, מצביעים ואפילו מבנים אחרים 2

הצהרה ( בעזרת דוגמא ) 3 struct book } char title[TITLE_LEN], author[AUTHOR_LEN], isbn[ISBN_LEN], language[LANG_LEN], publisher[PUBLISHER_LEN]; int pages; Date publication_date; {; המילה השמורה struct שם הטיפוס (רשות) מאפשר לנו להתייחס לטיפוס בהמשך המשתנים (שדות) המרכיבים את הטיפוס החדש שדה מטיפוס Date?

הצהרה תופיע בתחילת הקובץ לאחר הגדרות ה define מגדירה את התבנית הכללית של הטיפוס זו הצהרה על טיפוס ולא על משתנה! 4

נקודה במישור זוג סדור,,של מספרים המייצגים את מיקום הנקודה במישור נרצה למפות את הטיפוס המורכב לטיפוסים פשוטים יותר מכיל שני שדות x,y מהטיפוס הבסיסי double המייצגים קואורדינאטות במישור 5 struct point } double x, y; {;

עבודה עם מבנים המבנה הוא טיפוס כמו int, double, char* נגדיר משתנים מהטיפוס החדש 6 int main() } struct point p; int i; double d; {; שם הטיפוס שם המשתנה

כתיבה מקוצרת בעזרת typedef ניתן לחבר את הגדרת המבנה עם השם הנרדף וכאשר נשתמש typedef struct { double x, y; } point; double distance(point p, point q) {... } int main() { point p1, p2;... } 7

איתחול מבנים ( המשך ) שימו לב לאיתחול של השדה publication_date שהוא בעצמו מהטיפוס המורכב Date 8 book b = {"Alice in Wonderland", // title "Lewis Carroll", // author " X", // isbn "English", // language "Tribeca Books", // publisher 100, // pages {2010, 12, 12} // date };

פעולות על מבנים הפעולות היחידות המוגדרות על מבנה הן: גישה לשדה – האופרטור. (dot) כתובת המשתנה – אופרטור & (כמו עבור כל משתנה אחר) מחזיר את הכתובת של השדה הראשון במבנה השמה – אופרטור = ההשמה מתבצעת ע"י העתקה שדה-שדה ממשתנה אחד לשני לא מוגדרות: השוואה, פעולות אריתמטיות ולוגיות נדרש להגדיר פונקציות 9

השמה ניתן לבצע השמה בין שני משתנים מאותו טיפוס מורכב השמה מבוצעת עבור כל השדות שקול ל: 10 point p1, p2;... p1 = p2; point p1, p2;... p1.x = p2.x; p1.y = p2.y; העתקה של הערך במשתנה p1 למשתנה p2

פעולות אחרות לא מוגדרות פעולות אחרות על מבנים תלויות בטיפוס הספציפי מה המשמעות של שוויון בין נקודות? ספרים? נצטרך לממש אותן בעצמנו בעזרת פונקציות 11

מבנים ופונקציות בדיוק כמו משתנים רגילים call by value העתקת הערך של המשתנה למשתנה המקומי בפונקציה בשביל זה צריך השמה ניתן להחזיר משתנה שינוי המשתנה בתוך הפונקציה לא משפיע על המשתנה בפונקציה הקוראת 12

מצביעים למבנים ( ובכלל ) ופונקציות שינוי משתנה בעזרת מצביע למבנה שימוש במצביע למצביע 13

אופרטור החץ <- ( סוכר תחבירי ) במקום להשתמש בצירוף שדה.(מצביע*) כדי לגשת לשדה נוכל להשתמש באופרטור <- שינוי בתחביר בלבד זהו התחביר המועדף 14 int distance(const point* p1, const point* p2) { return sqrt( (p1->x – p2->x) * (p1->x – p2->x) + (p1->y – p2->y) * (p1->y – p2->y) ); }

בחירות מימוש ואבסטרקציה - מלבן כיצד נגדיר מלבן שצלעותיו מקבילות לצירים? נשתמש במבנה הנקודה שכבר הגדרנו bottom left top right typedef struct { point bottom_left, top_right; } rectangle; 15

מבנים - סיכום הגדרת טיפוסי משתנים חדשים שקרובים לעולם- הבעיה שימוש כמו בטיפוסים רגילים מערך של מבנים, מצביעים על מבנה, העברה לפונקציה וכו' מוגדרת פעולת ההשמה יש להגדיר פונקציות עבור פעולות אחרות (השוואה, אריתמטיות ועוד) 16

הקצאת זיכרון דינאמית 17

הקצאת זיכרון דינאמית לא תמיד כל המידע ידוע בזמן כתיבת התכנית לדוגמא, תלוי בקלט מהמשתמש ניתן להקצות זיכרון במהלך ריצת התכנית הזיכרון יוקצה באזור ה"ערימה" (heap) לא נעלם כאשר הפונקציה מסתיימת הקצאה ושחרור באחריות המתכנת 18

מודל הזיכרון של התכנית הקוד פקודות התכנית Data מחרוזות שהוגדרו ע"י המתכנת מחסנית (Stack) משמש לאיחסון משתנים לוקאליים Last In First Out (LIFO) בשליטת התכנית ערימה (Heap) בשליטת המתכנתת קריאה בלבד קריאה וכתיבה 19 קוד data מחסנית (stack) ערימה (heap)

הקצאה דינאמית בשפת C C מספקת לנו מנגנון בסיסי להקצאה ושחרור של זיכרון מוגדרות ב stdlib.h 20 פונקציהמטרה mallocהקצאת זיכרון בגודל מבוקש callocהקצאת מערך של אברים ואיתחולו ל-0 freeשחרור זיכרון שהוקצה קודם לכן reallocשינוי גודלו של זיכרון שהוקצה קודם לכן

הפונקציה malloc מקבלת את גודל הזיכרון שנרצה להקצות (בבתים) מחזירה את הכתובת לזיכרון שהוקצה NULL אם נכשלה תמיד יש לבדוק אם הקצאת הזיכרון הצליחה או נכשלה void *malloc(int nBytes) 21

malloc דוגמא הקצאה דינאמית של זיכרון בגודל 10 int האופרטור sizeof מחזיר את הגודל (בבתים) של הטיפוס המבוקש הפונקציה מחזירה כתובת (void*) באחריותנו להמיר את המצביע לטיפוס המתאים int main() { int *a = (int*) malloc(10 * sizeof(int));... return 0; } 22

הפונקציה free – שיחרור זיכרון באחריות המתכנת לשחרר זיכרון שהוקצה דינאמית ptr- מצביע לזיכרון שהוקצה דינאמית ptr- ערך מוחזר מקריאה ל-malloc, calloc או realloc אחרת שגיאה אין שיחרור חלקי של זיכרון void free(void *ptr) 23

הקצאת מערך בגודל התלוי במשתנה 24 int main() { int *a, size, i; printf("Enter array size\n"); scanf("%d", &size); a = (int*) malloc(size * sizeof(int)); if (a == NULL) return 1; for (i = 0; i < size; i++) scanf("%d", &a[i]); for (i = 0; i < size; i++) printf("%d", a[i]); free(a); return 0; } main a size i Stack Heap

פונקציות נוספות מקצה מערך של n איברים, כל איבר בגודל size_el בתים, כל בית מאותחל לאפס (ולכן פחות יעילה). מקבלת מצביע לזיכרון שהוקצה דינאמית ומספר בתים size הפונקציה מקצה זיכרון בהתאם לגודל הנדרש מעתיקה את תכולת הזיכרון הישן לחדש משחררת את הזיכרון הישן בשתי הפונקציות קריאה מוצלחת תחזיר את כתובת תחילת הזיכרון המוקצה, אחרת יוחזר NULL void* calloc( unsigned int n, unsigned int size_el ) 25 void* realloc( void *ptr, unsigned int size )

calloc - דוגמא 26 int main() { int *a, size, i; printf("Enter array size\n"); scanf("%d", &size); a = (int*) calloc(size, sizeof(int)); if (a == NULL) return 1; for (i = 0; i < size; i++) scanf("%d", &a[i]); for (i = 0; i < size; i++) printf("%d", a[i]); free(a); return 0; } הקצאת size אלמנטים, כל אלמנט בגודל sizeof(int) הפונקציה תאתחל את הזיכרון ל-0

realloc - דוגמא int *ptr = NULL; int size = 0, new_size = 0; scanf("%d", &size); ptr = (int*) malloc( size * sizeof(int) ); /* incomplete, must check if allocation succeeded */... scanf("%d", &new_size); ptr = (int*) realloc( ptr, new_size*sizeof(int) ); /* incomplete, must check if allocation succeeded */... if (ptr != NULL) free(ptr); הקצאת זיכרון הקצאת חדשה שחרור זיכרון 27

זיכרון שהוקצה דינאמית 28 int* func() { int *memPtr = NULL; memPtr = (int*) malloc(10 * sizeof(int));... return memPtr; } int main() { int * ptr = func(); if (ptr != NULL) { // do something with ptr free(ptr); ptr = NULL; } memPtr ptr מותר להחזיר כתובת לזיכרון שהוקצה דינאמית הזיכרון שייך לתוכנית ולא לפונקציה

שיחרור זיכרון אפשרות א': הפונקציה שהקצתה האפשרות המועדפת – כותב הפונקציה אחראי על הזיכרון הדינאמי אפשרות ב': החזרת הכתובת האחריות עוברת למי שקרא לפונקציה המקצה חובה לתעד זאת, אחרת "דליפת זיכרון" עלינו להימנע ממצב שבו יש הקצאת זיכרון אבל לא מתקיים א' או ב' 29

קריאת שורת קלט בגודל לא ידוע ( מערך דינאמי ) 30 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT * sizeof(char); } buffer[index++] = c; } buffer[index] = '\0'; return buffer; }

קריאת שורת קלט בגודל לא ידוע 31 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } מערך בגודל התחלתי כלשהו

קריאת שורת קלט בגודל לא ידוע 32 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } יש לוודא שהקצאת הזיכרון לא נכשלה

קריאת שורת קלט בגודל לא ידוע 33 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } קריאת קלט מהמשתמש עד לסוף השורה

קריאת שורת קלט בגודל לא ידוע 34 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } האם נגמר המקום?

קריאת שורת קלט בגודל לא ידוע 35 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } נקצה מערך גדול יותר

קריאת שורת קלט בגודל לא ידוע 36 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } לא לשכוח לבדוק

קריאת שורת קלט בגודל לא ידוע 37 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } לא לשכוח לעדכן את capacity

קריאת שורת קלט בגודל לא ידוע 38 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } נשמור את התו שקראנו במקום המתאים

קריאת שורת קלט בגודל לא ידוע 39 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } בסוף נוסיף ‘\0’

קריאת שורת קלט בגודל לא ידוע 40 char* readLine() { int index = 0, c, capacity = INITIAL_SIZE; char *buffer = (char*) malloc(capacity * sizeof(char)); if (buffer == NULL) return NULL; for (c = getchar(); c != '\n'; c = getchar()) { if (index == capacity – 1) { buffer = (char*) realloc(buffer, capacity * INCREMENT * sizeof(char)); if (buffer == NULL) return NULL; capacity = capacity * INCREMENT; } buffer[index++] = c; } buffer[index] = '\0'; return buffer; } מחזירים זיכרון שהוקצה דינאמית – באחריות הלקוח לשחרר (צריך לתעד)

שימוש ב readLine 41 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } קריאת שורת קלט מהמשתמש

שימוש ב readLine 42 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } אם הייתה בעיה נדפיס הודעת שגיאה ונסיים

שימוש ב readLine 43 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } שימו לב לערך המוחזר

שימוש ב readLine 44 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } נשתמש בקלט

שימוש ב readLine 45 int main() { char *line = readLine(); if (line == NULL) { printf("Fatal error: memory allocation failed!\n"); return 1; } printf("%s\n", line); free(line); return 0; } כשאיננו צריכים יותר את הקלט, נשחרר את הזיכרון

הקצאת זיכרון - בעיות נדיר שהקצאת הזיכרון נכשלת אפשרויות לטיפול: החזרת הערך NULL מהפונקציה - כאשר תפקיד הפונקציה הוא הקצאת הזיכרון שימוש בפונקציה exit לסיום התכנית

הפונקציה exit מוגדרת ב stdlib.h מסיימת את התכנית באופן מיידי נשתמש רק כאשר מתרחשת בעיה שאין לנו שום דרך לטפל בה בדרך כלל נדפיס הודעת שגיאה למשתמש ונסיים את תכנית void exit(int status);

דוגמה לשימוש ב -exit נשנה את גודלו של מערך של int בעזרת realloc אם השינוי נכשל, נסיים את התכנית 48 int* resize(int *array, int newSize) { if (array == NULL) return array; array = (int*) realloc(array, newSize * sizeof(int)); if (array == NULL) { printf("Fatal error: memory allocation failed!\n"); exit(1); } return array; }

הקצאה דינאמית של מבנים בדיוק כמו בטיפוסים בסיסיים 49 typedef struct { char *title, *author; } Book; Book* newBook(const char *title, const char *author) { Book *result = (Book*) malloc(sizeof(Book)); /* incomplete, must check if allocation succeeded */ result->title = (char*) malloc(strlen(title) + 1); /* incomplete, must check if allocation succeeded */ strcpy(result->title, title); result->author = (char*) malloc(strlen(author) + 1); /* incomplete, must check if allocation succeeded */ strcpy(result->author, author); return result; }

הקצאה דינאמית של מערכים דו - ממדיים (לפחות) שלוש גישות אפשריות: 1.מערך של מערכים 2.מצביעים לתוך מערך "גדול" 3.מצביע יחיד למערך גדול 50

מערך של מערכים 51 int main() { int rows, cols, i; int** table; scanf("%d%d", &rows, &cols); table = (int**) malloc(rows * sizeof(int*)); /* incomplete, must check if failed */ for (i = 0; i < rows; i++) { table[i] = (int*) malloc(cols * sizeof(int)); /* incomplete, must check if failed */ } init_table(table, rows, cols); print_table(table, rows, cols); for (i = 0; i < rows; i++) free(table[i]); free(table); return EXIT_SUCCESS; }

איתחול והדפסה 52 void init_table(int **table, int rows, int cols) { int i, j; for (i = 0; i < rows; i++) for (j = 0; j < cols; j++) table[i][j] = (i + 1) * (j + 1); } void print_table(int **table, int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) printf("%4d", table[i][j]); printf("\n"); } }

מצביעים למערך גדול 53 int main() { int rows, cols, i; int* data; int** table; scanf("%d%d", &rows, &cols); data = (int*) malloc(rows * cols * sizeof(int)); /* incomplete, must check if failed */ table = (int**) malloc(rows * sizeof(int*)); /* incomplete, must check if failed */ for (i = 0; i < rows; i++) table[i] = data + (cols * i); init_table(table, rows, cols); print_table(table, rows, cols); free(table); free(data); return EXIT_SUCCESS; }

מצביע יחיד למערך גדול – בהמשך היום... 54

הצצה לייצוג ועיבוד תמונה 55

56 Digital Images Digital image is a numeric representation of a two-dimensional image Examples: photos, microscopic, medical, astronomical

57 Image Representation Encoded as a n-by-m matrix M Each element M[x,y] in an image is called picture element (pixel), representing the light intensity / color at that location RGB, gray-level images, binary images Video – an image for each time t

58 Pixel Resolution (pixel count)

Image Quantization Number of bits per pixel 24 bit RGB16 colors Note that both images have the same pixel & spatial resolution

60 Gray Level Images The remaining of class will deal with gray-level images (although can be applicable for color images) 8 bits per pixel (256 gray levels), 0 – black, 255 – white Other representations: Binary – 1bit per pixel Some applications use more colors (medical imaging)

61 An Example

62 Image Processing Signal processing for which the input is an image Typical operations: Color corrections / calibration Image segmentation Image registration / alignment Denoising Typical applications: Machine vision Medical image processing Face detection Augmented reality

63 In C How to handle an image? OpenCV Library Image processing in C (book): More libraries Eyal’s code (for your HW)… Capacities: Read / write images Display image Basic image processing

64 Image Representation (bmp.h, bmp.c) BMP file format Representation: BMP Image file header - meta data about the image Data – one dimensional array that holds the pixels values Functionality: Read an image from a file Write an image structure to a file Initiate BMP header (to create new images)

65 The Interface

66 The Header

67 (Simple) Usage Examples Access to header’s width (same for height): bh->info->width

68 More Examples In Tirgul

69 Image Segmentation

70 Image Segmentation Algorithms Thersholding Clustering Region growing Compression-based methods Histogram-based methods Model-based methods Etc.

71 Thresholding Simplest segmentation method Apply a threshold to turn a gray-scale image into a binary image The key is to select the appropriate threshold value Popular method – Otsu’s method (maximal variance)

72 Example TH = 20TH = 80 TH = 140TH = 180

73 Similarity Between Images Image histogram Normalized histograms Similarity measures between images using histograms Metrics: L1, L2

74 (Simple) Resize / Downscale Images Less pixels to represent the same image Some pixels from the original map are mapped to a single pixel in the output image (e.g., by averaging)

75 HW Compute an image’s histogram Compute a threshold to achieve x% of black (0) pixels based on its histogram, return the new segmented image Compute the L2 similarity measure between pairs of images Downscale images Removed

76 Real World Application Face Detection Credit: Intel Technology Journal, Volume 09, Issue 01

77