בעיה בC

Keves209

New member
בעיה בC

יש לי מערכת בC שיושבת על unix, וכך אני גם מקמפל אותה.. איפשהו בתכנית יש לי מערך של מבנים שאני צריך להגדיר בגודל של 10000000, משום מה הקומפיילר לא נותן לי ואומר שזה מעבר לגודל המותר בשבילו או משהו בסגנון, מישהו יודע איך אני יכול לבצע פעולה כזאת?
 

ahab

New member
איפה אתה מקצה אותו?

אם אתה מנסה להקצות אותו על המחסנית
struct BigStruct arr[100000000];​
אז אני מבין את הקומפיילר. לרוב גודל המחסנית מוגבל, ואתה לא יכול להקצות מערך גדול מדי עליה. אתה תמיד יכול להקצות את המערך באופן דינמי (להגדיר מצביע, ולהקצות את המערך ע"י malloc). בשיטה זו, רק המצביע יהיה על המחסנית, והמערך עצמו יהיה ב-heap.
 

Keves209

New member
אין לי מושג

מה הכוונה בלהקצות על המחסנית או בHeap?? אני פשוט מגדיר #define MAX_MIKTZOOT 10000000 long miktzoot[MAX_MIKTZOOT]
 

DarkSwell

New member
תבדוק שאתה לא על model small

אבל בכל אופן לא נראה לי יעיל ליצור מערך כזה גדול, עדיף במהלך הריצה להקצות כל פעם תא נוסף לפי הצורך. ב model small מוקצה לך עבור סגמנט הנתונים 64K בלבד.
 

annefan

New member
בשום מודל הוא לא יכול

long הוא ארבעה בתים. הוא מקצה 10000000 - עשרה מיליון. הוא צריך stack בגודל 40000000 רק למערך הזה. stack ב-windows הוא 8 MB. (כמובן, שיתכן צירוף של קומפיילר+מעה"פ+דגלים מתאימים לאפשר את זה. מעשית, הוא לא יכול.)
 

DadleFish

New member
זה דווקא לא נכון,

ה-STACK הרגיל ש-VS מקצה לכל THREAD הוא 10MB, וניתן כמובן להגדיל אותו לפי הצורך.
 

OriIdan

New member
small model?

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

Keves209

New member
אהבתי את ההתנשאות

אבל זה פרוייקט שקיים כבר מ96, ולשנות את איך שהוא פועל זה לא ריאלי לכן אני צריך להתאים את עצמי לקיים. דבר ראשון זה על UNIX, ואין הגבלה כל כך על הSTACK וכאלה, וחוץ מזה כבר מוקצה לי בתכנית מערך בגודל 5000000 של מבנים שמכילים יותר מlong או שניים ככה שבטוח אפשר לעשות את זה. נ.ב. תאמין לי שאם היה לך מושג מה סדר הגודל והזמינות של המערכת לא היית מדבר ככה.
 

ahab

New member
גם ב-unix יש הגבלות

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

Keves209

New member
זהו שאני לא יודע איך

להקצות אותם במקום מסויים? ומה זאת אומרת? אני יודע שיש פקודה שנקראת far, רק אני לא זוכר אם היא קיימת גם בC, או שהיא של C++, ואם היא בכלל תעזור.
 

OriIdan

New member
למה בכלל להשתמש בהקצאה סטטית?

במקרים כאלו מומלץ להשתמש בהקצאה דינמית שאז הזכרון מוקצה ב HEAP שגודלו בלתי מוגבל (בעצם מוגבל בכמות הזכרון הוירטואלי במערכת).
 

Keves209

New member
כן זה כנראה מה שאני אעשה

רק רציתי רציתי לדעת למה זה לא נתן לי לעשות את זה.. תודה רבה!
 

OriIdan

New member
יש מגבלה על גודל stack

בגלל המגבלה על גודל stack סביר להניח שלא הצלחת. תנסה להגדיר את זה כמשתנה גלובלי, אולי תצליח וגם זה לא בטוח כי יש גם מגבלה על גודל הנתונים הסטטיים.
 

OriIdan

New member
לא הייתה כוונה להתנשאות

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

annefan

New member
זו הקצאה על המחסנית

אתה לא יכול להקצות כל ככך הרבה מקום. חפש חומר על malloc ו-free ב-C, או new ו-delete ב++C.
#define MAX_MIKTZOOT 10000000 long * miktzoot = malloc(MAX_MIKTZOOT); ... free (miktzoot);​
 

ahab

New member
רק תיקון קטן

malloc מקבל בתור פרמטר את מספר הבתים להקצות. ולכן כדאי (מאוד) להעביר MAX_MIKTZOOT*sizeof(float) d כפרמטר ל-malloc (ללא ה-d, כמובן)
 
למעלה