الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

المصفوفات الديناميكية باستخدام الثوابت

بدأه HaTy في 27 نوفمبر 2008 · 14 رد · 2,017 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

هل يمكن انشاء مصفوفة ديناميكية والمستخدم يقوم بتحديد عدد عناصرها ؟

هذه محاولتي

  1. #include <stdio.h>

  2.  
  3. const num = 100000 ;
  4.  
  5. main()
  6. {
  7. int ary[num];
  8. int your_num;
  9.  
  10. printf("enter your array size ");
  11. scanf("%d",&your_num);
  12.  
  13. #undef num
  14. #define num your_num
  15.  
  16. for (int i = 0;i < num ; i++)
  17. {
  18. ary[i]=i;
  19. printf("%d n",ary[i]);
  20. }
  21.  
  22. printf("Constant : num = %d n",num);
  23.  
  24. return 0;
  25.  
  26. }
  27.  

سؤال هل تم بالفعل تغيير قيمة الثابت num فعلا ؟

اعيدوا تجربة المثال بتغيير قيمة الثابت num من 100000 الى 10

وعند تطبيق المثال ادخلوا قيمة اكبر 42 ولاحظوا الفرق

HaTy_Array.rar

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#2

وعليكــم السـلام ورحمة الله وبركاتـه..

بصراحة لم افهم المطلوب من سؤالك جيدا , لكن اذا كنت تريد ان تنشأ مصفوفة ديناميكية بواسطة لغة سي ++ , استخدم التابع new ولتحريرها تستخدم التابع delete

اما في سي , تستخدم التوابع المناظره , malloc و free

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#4

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

شكرا اخي time1 - شكرا اخي عمر

لم اكن اعرف new و delete

فبارك الله فيكم و نفع بكما

وفي المثال السابق قمت بتحديد عدد عناصر المصفوفة باستخدام الثابت num

ثم قمت بالغاء تعريف الثابت ثم تغيير قيمته num لتحجيم المصفوفة

.......

قد قرأت سابقا انه لا يمكن تغيير قيمة الثابت Constant

ولكن في المثال السابق بعدما الغيت تعريف الثابت num ثم اعادة تعريفه و تحجيمه من جديد

تغيرت قيمة الثابت num المخرجة من البرنامج

فهل تغيرت قيمة الثابت num في الذاكرة فعلا ؟

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#5

أخى ما حدث فى كودك ان حصل شئ اسمه Overflow لأن من الممكن ان يدخل المستخدم رقم أكبر من 100000 لذلك سوف يكتب المعلومات الزائدة خارج عناوين المصفوفة

انا جربت الكود و اعطانى بعد انتهائه رسالة خطأ ، و هذا معناه ان البرنامج كتب فى الذاكرة فى اماكن غير مخصصة له ، حدث Buffer Overflow

Buffer_overflow

#6
#undef num

أنت لم تقم اصلا بتعريف (define) لـnum , أعد النظر في الكود مرة اخرى, هل فهمت ما أقصد ؟

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#7

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

شكرا اخي الكريم عمر فهمت الان

...

لاحظت ان اكبر عدد لعناصر المصفوفة من النوع int يجب ان لا يتجاوز 258563

...

GamingMasteR كتب:
#undef num

أنت لم تقم اصلا بتعريف (define) لـnum , أعد النظر في الكود مرة اخرى, هل فهمت ما أقصد ؟

كلامك صحيح اخي الكريم

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#8
اقتباس
لاحظت ان اكبر عدد لعناصر المصفوفة من النوع int يجب ان لا يتجاوز 258563

لماذا ؟؟ :blink: :wacko:

هل هذا أكبر حجم للذاكرة ،،

4 bytes × 258563 = 1034252 bytes = 0.986 mb

حجم صغيييييييير جداً

#9

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

اهلا اخي عمر

Omar Eladel كتب:
لماذا ؟؟ :blink: :wacko:

هل هذا أكبر حجم للذاكرة ،،

4 bytes × 258563 = 1034252 bytes = 0.986 mb

حجم صغيييييييير جداً

حسنا جرب هذا المثال , حتى تتأكد

  1. #include <stdio.h>

  2.  
  3. main()
  4. {
  5. int ary[300000];
  6.  
  7. for (int i = 0;i < 300000 ; i++)
  8. {
  9. ary[i]=i;
  10. printf("%d n",ary[i]);
  11. }
  12. return 0;
  13.  
  14. }
  15.  

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#10

عليك ان تعرف انواع حجز الذاكرة المختلفة أولاً .. ما قمت به هو حجز من الـStack .

الـStack له حجم ثابت يتم تحديده اثناء عملية الـlinking للبرنامج و الحجم الذي تطلبه انت اكبر من المتوفر في الـStack لذلك سيحدث طفح Overflow .

في هذه الحالة - حجز كمية كبيرة من الذاكرة - فالحجز من الـHeap او الـVM أفضل :

int *ary = new int [300000];

--------------------

بالمناسبة يمكن ان يعمل البرنامج أيضاً بالحجز من الـStack كما فعلت أنت ... لكنّي اريدك انت ان تبحث وتخبرني كيف يمكن هذا (لقد اعطيتك أمارة ;))

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#11

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

اهلا خي الكريم

GamingMasteR كتب:
عليك ان تعرف انواع حجز الذاكرة المختلفة أولاً .. ما قمت به هو حجز من بالمناسبة يمكن ان يعمل البرنامج أيضاً بالحجز من الـStack كما فعلت أنت ... لكنّي اريدك انت ان تبحث وتخبرني كيف يمكن هذا (لقد اعطيتك أمارة ;) )

هل هذا هو الحل ؟

  1. static int ary[300000];

  2.  

تحياتي

تم تعديل هذه المشاركة بواسطة haty في 28 نوفمبر 2008 في 13:09

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#12

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

اخواني الاعزاء time1 - Omar - GamingMaster

حياكم الله و بياكم وجعل الجنة مثوانا و مثواكم

تعلمت منكم الكثير فبارك الله فيكم وشكرا على صبركم معنا

وهذا مثال للمصفوفة الديناميكية لاخواني المبتدئين مثلي

  1. #include <stdio.h>

  2. #include <iostream.h>
  3. main()
  4. {
  5. int max;
  6. cout<<"Enter Array Size : ";
  7. cin>>max;
  8. int* ary=new int [max];
  9.  
  10. for (int i = 0;i < max ; i++)
  11. {
  12. ary[i]=i;
  13. printf("%d n",ary[i]);
  14. }
  15.  
  16. return 0;
  17.  
  18. }
  19.  

و السلام عليكــم ورحمـة الله وبركاتــه

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#13
اقتباس
هل هذا هو الحل ؟

هذا ليس حجز من الـStack فجعله static يؤدي الى حجزه من الذاكرة المخصصة للبرنامج (File Image) .

حجز ذاكرة كبيرة من الـFile Image ليس جيد دائما ... في الحالة السابقة لن تشعر بفرق لأن المتغيرات التي تريد حجزها Uninitialized لكن ان قمت بوضع قيمة ابتدائية للمتغيرات ستعرف الفرق :

static int ary[300000] = {1};

الآن انظر الى حجم البرنامج الناتج :D

------------

ما اريدك ان تفعله هو زيادة حجم الـStack للبرنامج وذلك من خيارات الـLinker .

تم تعديل هذه المشاركة بواسطة GamingMasteR في 28 نوفمبر 2008 في 14:00

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#14

بارك الله فيك أخى haty ، احييك على مثابرتك للوصول الى الحل النهائى لمشكلتك بعد بعد بحث و مناقشة ،، واصل للنهاية وفقك الله ،

هذا المثال ما هو سى++ ولا هو سى ، هو خليط :D ، لأن لغة السى ليس فيها new و delete و انت استخدمت printf و هى من دوال السى

كان يجب عليك تحرير الذاكرة بعد نهاية البرنامج باستخدام delete[]

المثال بعد التعديل :

#include <iostream>
using namespace std;

int main(void)
{
	int max;
	cout << "Enter size of array: ";
	cin >> max;

	int* a = new int[max];

	for(int i=0; i<max; i++)
	{
		a = i*2;
		cout << a << endl;
	}

	delete[] a;

	system("pause");
	return 0;
}

بارك الله فيك ،،

اضافة : شكرا اخى GM على المعلومة الرائعة ،، انا جربت فعلاً و وجدت حجم البرنامج 1.59 mb

تم تعديل هذه المشاركة بواسطة Omar Eladel في 28 نوفمبر 2008 في 14:04

#15

بســم الله الـرحمــن الرحيــم

السلام عليكــم ورحمـة الله وبركاتــه

شكرا اخي الكريم عمر على تنقيح الكود و الاشارة للاخطاء فيه

مع ملاحظة ان using Namespace std; تمنع ترجمة البرنامج عندي - انا استخدم اصدار الفيجول السادس

... ... ...

اخي الكريم GamingMasteR شكرا على ال Hint

وعليه سيكون الحل كالاتي

Project -> Setting -> Link

...' From Category ... Choose ' OutPut

...' Then Set The Desired Size In The Box Titled ' Reserve

عادة ما يكون حجم ال Stack المبدئي 1 MB , ويمكن تحديد القيمة المطلوبة بالعشري او الهيكس

مثلا عشري 300000

سادس عشري 0X493E0

post-129961-1227875109_thumb.png

ولكن هل يوجد طريقة بالكود ؟ مماثلة للدالة

  1. HRESULT __stdcall get_StackCommitSize( [out, retval] long* retVal);

  2.  
  3.  

مثلا

  1. __stdcall set_StackReserveSize( long* setVal);
  2.  
  3.  

بورك فيكم جميعا

تحياتي

تم تعديل هذه المشاركة بواسطة haty في 28 نوفمبر 2008 في 15:39

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";

مواضيع مشابهة