الشبكة العربية لمطوري الألعاب

خبير  Mohammad Khashashneh مشاركة 1

Good afternoon, I have trouble getting rid of a warning because of a casting problem.
/*step1*/
char (*pArray) [ARRAY_SIZE];
/*step2*/
char * buffer = malloc (BUFFER_SIZE);
/*step3*/
pArray = buffer ;
/*step4*/
pArray [x][y] = 10 ;


warning: assignment from incompatible pointer type


First I defined a pointer to an array of bytes. then allocated a buffer and made the pointer point to that buffer (step3), to use it as in step4

That worked fine , but I have a warning regarding the assignment in step3.
I tried to make a new type of pointer to array using typedef, and casted the assignment in step3 to it. I was able to get rid of the warning, but the runtime is not so true.
typedef char ARRAY[ARRAY_SIZE];
typedef array *PARRAY ;
PARRAY pArray ;
pArray = (PARRAY)buffer ;
pArray [x] [y] = 10 ;


I welcome any ideas regarding the typedef or any other way to compile with no warnings☺
Note: I am using C here.

من سار على الدرب وصل, من جد وجد...
بس عتبك على اللي بيسمع

خبير مدير وسام البهنسي مشاركة 2

ما الوظيفة التي تريد الحصول عليها والنتيجة التي تتوقعها؟
يبدو لي للوهلة الأولى أنك تريد التعامل مع مصفوفة 2D، لكن هذا غير واضح تماماً من الكود...



MSDN Game Technology Forums Moderator

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

خبير  Mohammad Khashashneh مشاركة 3

Yep, This is what I am trying to do. I want to manipulate the buffer in a 2D array Fashion. easier for computation ;)

من سار على الدرب وصل, من جد وجد...
بس عتبك على اللي بيسمع

خبير  Mohammad Khashashneh مشاركة 4

Hello, I just solved the problem. The Typedef method now works fine. the runtime error was related to something else.

Thanks again.

من سار على الدرب وصل, من جد وجد...
بس عتبك على اللي بيسمع

خبير  أحمد عبد الغني مشاركة 5

لكن المبدأ غير سليم...
الصيغة:
pArray[x][y]

تعني الوصول إلى المصفوفة الخطية x ثم جلب العنصر رقم y.
لكن طريقة إسنادك الذاكرة لـ pArray لا تنفع لأنك تقوم بإسناد ذاكرة خطية فقط بدون عنواين (أي أن خطوة جلب المصفوفة x غير سليمة)...

هل أنت متأكد أنك لا تقوم بتخريب الذاكرة عند استخدام هذه الحيلة؟

اللهم انصر أهلنا في فلسطين وآجرنا أن نكون عوناً لهم

خبير مدير وسام البهنسي مشاركة 6

إن كان الهدف هو التعامل مع مصفوفة خطية بشكل 2D فيمكن استخدام الأسلوب:
pArray = new int[width*height];
pArray[x+width*h] = 10;

أعتقد أنها بسيطة بما يكفي، ومن ناحية الأداء، فهي تفوق الوصول إلى عنصر عن طريق مؤشرين لأن المترجم عادة يفتقد لهذا العمق من التوقع، مما قد يتسبب بإعادة تحميل العنوان إلى السجلات عند كل محاولة وصول... أقول عادةً!


MSDN Game Technology Forums Moderator

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 7

التعليق على مشاركة وسام البهنسي في July 20, 2006 18:37 :

> أعتقد أنها بسيطة بما يكفي، ومن ناحية الأداء،
> فهي تفوق الوصول إلى عنصر عن طريق مؤشرين لأن المترجم
> عادة يفتقد لهذا العمق من التوقع، مما قد يتسبب بإعادة
> تحميل العنوان إلى السجلات عند كل محاولة وصول... أقول
> عادةً!
>

هل أنت متأكد؟ أذكر أني قرأت في أحد كتب الـ Assembly أن ما يفعله المترجم هو بالضبط ما أشرت إليه. أي أن تعليمة كـ: pArray[x][y] ستترجم إلى ما يشبهpArray[x+width*y] قد أكون مخطئاً...
أظن أن طريقة محمد طريقة ذكية فعلاً في التعامل مع الـمصفوفات الديناميكية ثنائية البعد بطريقة تشبه تلك التي ليست ديناميكية

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مدير وسام البهنسي مشاركة 8

التعليق على مشاركة Abdo Haji-Ali في July 21, 2006 13:32 :

> هل أنت متأكد؟ أذكر أني قرأت في أحد
> كتي الـ Assembly أن ما يفعله المترجم هو بالضبط ما أشرت
> إليه. أي أن تعليمة كـ: pArray[x][y] ستترجم إلى ما يشبهpArray[x+width*y]

نعم متأكد على الأقل بالنسبة لمترجم Microsoft للـ x86 والـ Xbox، ومترجم SN للـ Playstation 2.

أعتقد أن رد أحمد عبد الغني يوضح تماماً الموقف. أنت لا تتعامل مع مصفوفة ثنائية البعد محجوزة بشكل خطي. أنت تتعامل مع مصفوفة مؤشرات إلى مصفوفات خطية. مما قد يعني أن كل من هذه المؤشرات قد يؤشر إلى منطقة مختلفة في الذاكرة. لاحظ أنك تستخدم نفس البنية اللغوية في التعامل مع الـ Jagged Arrays مما يؤكد وجهة نظري.

الحالة الوحيدة التي قد تعمل (وأشك في ذلك كثييييراً) هو أن تعلن عن المصفوفة كنوع مكون من أبعاد ثابتة، ثم تقوم بتغيير عنوان المتغير الأساسي إلى مصفوفة ديناميكية خطية تتسع لنفس العدد من العناصر. لاحظ أن هذا يلغي فائدة التكنيك كلها لأنك مربوط بأبعاد مسبقة التحديد (ليست ديناميكية)...


MSDN Game Technology Forums Moderator

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 9

حسناً. اسمحوا لي أن ألخص الموضوع:

هناك نوعان من الـ 2D Arrays في C الأول static و الآخر dynamic:
1. Static
int aaArray[height][width];

هذا النوع يستخدم داخلياً للوصول إلى x,y المعادلة التالية:
*(aaArray + y*width + x);

لاحظ أن هذه المصفوفة "متتابعة" Continuous في الذاكرة... و هذا ما يسمى بالـ Rectangular Arrays
2. Dynamic
int **ppArray;

يمكنك حجز هذه المصفوفة بأي طريقة تريد. لاحظ أن العنصر الأساسي في هذا النوع هو المؤشر من الدرجة الثانية int** و هذا النوع ستخدم داخلياً المعادلة التالية للوصول إلى x,y
*(*(ppArray + x) + y);

هنا كل عنصر أولي (ppArray[x]) هو مؤشر لمصفوفة مستقلة يمكن أن تكون في مكان مستقل تماماً عن المصفوفة الأولى في الذاكرة و هذا ما يسمى بالـ Jagged Arrays

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير  أحمد عبد الغني مشاركة 10

وأضيف أنه لا يمكنك أن تحول من الـ static إلى dynamic.
وحتى إن أجبرت المترجم على ذلك فانت تخرب الذاكرة
وهذا ما عنيته بردي الأول...

اللهم انصر أهلنا في فلسطين وآجرنا أن نكون عوناً لهم