לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תכנות ובניית אתרים
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 18-05-2012, 23:07
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
שאלה ב C - הקצאות דינאמיות ומצביעים

נראה לי שכבר שכחתי C... ניסיתי לכתוב תוכנית ממש פשוטה, ואני מקבל התראה ממערכת ההפעלה
שאני חורג מהזיכרון והתוכנית קורסת.

מה שהיא צריכה לעשות זה לקבל כקלט מהמשתמש את הגודל של המערך, ולאחר מכן לאפשר הוספה / הסרה של איברים. הגודל יהיה דינאמי ובינתיים הספקתי לטפל רק בחלק שמגדיל את המערך (ידנית עם מאלוק וללא שימוש בריאלוק).
משום מה, בשורה 77 אני מקבל את השגיאה שציינתי קודם, והתוכנית קורסת ואני פשוט לא מבין מה עשיתי לא נכון.
שגיאה זו מתקבלת כבר בהכנסת הערך הראשון, עוד לפני שאני מטפל בהגדלת המערך אם הגיע לקצה הקיבולת שלו.
אשמח לעזרתכם :-)


קוד PHP:
 #include <stdio.h>

int show_menu();
int set_array_size(int*);
int insert(int*, int*, int);

int main()
{
    
int *array, menu_option, exit = 0index 0array_size;
    
array_size set_array_size(array);
    while (!exit)
    {
        
menu_option show_menu();
        switch(
menu_option)
        {
            case 
1:
                
array_size insert (array, &indexarray_size);
                break;
            case 
2:
                
printf("remove\n");
                break;
            case 
3:
                
printf("print\n");
                break;
            case 
4:
                exit = 
1;
                break;
            default:
                
printf("You pressed a bad key. Try again\n");
                break;
        }
    }
    return 
0;
}

int show_menu()
{
    
int menu_select;
    
printf("*** MENU ***\n1. Insert a value to the array\n2. Remove a value from the array\n3. Print the array\n4. Exit\n");
    
scanf ("%d", &menu_select);
    return 
menu_select;
}

int set_array_size(int* array)
{
    
int size;
    
printf("Insert array size: ");
    
scanf ("%d", &size);
    array = (
int*) malloc (sizeof(int) * size);
    if (array != 
NULL)
    {
        return 
size;
    }
    else
    {
        
printf("Error allocating memory!");
        return 
0;
    }
}

int insert(int *array, intindexint size)
{
    
int new_data, *temp_arrayi;
    
printf("insert a value to the array: ");
    
scanf ("%d", &new_data);
    if (*
index size// The array is too small. Need to allocate more memory
    
{
        
size *= 2;
        
temp_array = (int*) malloc (sizeof(int) * size);
        for (
size i++)
        {
            
temp_array[i] = array[i];
        }
        
free(array);
        array = 
temp_array;
    }
    array[*
index] = new_data// <-- this is where my program crushes and burns
    
*index++;
    return 
size;

_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #3  
ישן 19-05-2012, 14:42
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 2 שנכתבה על ידי RP. שמתחילה ב "הבעיה היא שאתה מעביר מצביע..."

לא הבנתי, אם אני שולח את המערך שלי לתוך מצביע, זה אומר שיש לי משתנה חדש שמחזיק
בתוכו (כלומר הערך שלו) את הכתובת של המערך, לא?
את הפעולה אני אעשה לא על המצביע עצמו אלא על הערך שבתוך המצביע?
ניסיתי לעשות משהו כזה:
קוד PHP:
 *(array[*index]) = ... 

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

תודה לכם על העזרה. להסיר חלודה מ C זה תמיד נחמד :-)

נ.ב - בשביל מה stdlib ?
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #11  
ישן 20-05-2012, 23:54
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 9 שנכתבה על ידי Narxx שמתחילה ב "שובי, למה אני צריך מצביע..."

תראה, יש שתי דרכים להסתכל על זה:

אם המטרה שלך היא ללמד לכתוב קוד יפה וטוב, אז יש שני דברים שאפשר לעשות כדי
למנוע הסתבכויות כאלה ב-C.

הראשון הוא להשתמש ב-typedef כדי להקל על הצורך לעקוב אחרי כמות הכוכביות
כשמתעסקים עם מצביעים. ברגע שאתה מגדיר typedef int* array_of_int;‎
ו-typdef double * dobule_out;‎, אתה לא צריך לדעת שפרמטר out של מערך
של int צריך להיות typdef int** array_of_int_out;‎ כי אתה פשוט אומר
typedef array_of_int* array_of_int_out;‎.

כנ"ל לגבי מחרוזות. אם אתה רוצה להוציא מחרוזת אתה צריך להשתמש בפרמטר מסוג
char**‎ (לדוגמה: void get_string(char** buf, size_t size);),
אבל אם אתה לא מבין למה צריך שתי כוכביות, ה-typdef-ים עונים על השאלה:
typdef char* c_string;
typedef c_string* c_string_out;

הדבר השני הוא להשתמש ב-struct-ים ובפונקציות כדי לעטוף דברים מגעילים כמו מערכי
C. מערך ב-C ברוב המקרים 'דועך' למצביע, ואין לו גודל. בגלל זה כל הזמן צריך לדאוג
שיהיה פרמרט נוסף של גודל. זה מעצבן ומוביל לשאלות ותשובות כמו למעלה.

יותר קל להגיד דבר כזה:
typedef struct
{
int * arr;
size_t size;
} array_of_int;

ולסדר פונקציות כאלה (בערך!):
array_of_int create_array_of_int(size_t size)
{
array_of_int new_arr = {0};
new_arr.arr = (int*) malloc(size * sizeof(int));
if (new_arr.arr != NULL)
{
new_arr.size = size;
}
return new_arr;
}
אתה מעביר 2 בייט גם ככה וגם ככה, אבל עם ה-struct אתה לא שוכח בטעות להעביר
את הגודל...

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

אמר פסטן: שניהם גרועים, אבל עדיף להיות טיפש מאשר שקרן.
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #13  
ישן 19-05-2012, 22:09
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,751
בתגובה להודעה מספר 1 שנכתבה על ידי Narxx שמתחילה ב "שאלה ב C - הקצאות דינאמיות ומצביעים"

בנוסף לכל הדברים שאמרו לך, קצת הערות סגנון:
  • אם כבר יש לך פונקציה show_menu, כדאי שתהיה לך גם פונקציית handle_user_selection או משהו כזה, ואז הלולאה וה-main יוצאות קצרות ופשוטות.
  • תגדיר משתנים מרמות שונות של פוינטרים בשורות נפרדות. זה יכול להיות מבלבל (בשורה הראשונה ב-main ובשורה הראשונה ב-insert).
  • תגדיר את menu_option בתוך הלולאה. ממילא אין במשתנה שימוש מחוץ לה.
  • תאתחל את array_size ישר בהגדרה שלו במקום בנפרד.
חוץ מזה, עדיף לא להשתמש ב-scanf לקליטת קלט מהמשתמש, ככה אומרים...
עדיף לקלוט מחרוזת (fgets וכד') ולפרסר אותה אחרי זה. שימוש ב-scanf על stdin או על קובץ שאתה לא ממש ממש ממש בטוח שמגיע בפורמט הנכון יכול לגרום לתוצאות מוזרות.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

אמר פסטן: שניהם גרועים, אבל עדיף להיות טיפש מאשר שקרן.
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 00:05

הדף נוצר ב 0.10 שניות עם 12 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר