View Full Version : آرایه ها در سی
1485159
یک شنبه 07 تیر 1388, 14:01 عصر
آرایه ها در سی
من یه سوالی توی آرایه ها داشتم و اون هم اینه که مثلا مایه آرایه تعریف کردیم:
char x[5];
حالا ما میتونیم مقدار بدیم:
x[60]='a';
این چطور ممکنه؟
ویا :
//---------------------------------------------------------------------------
#include <stdio.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
char d[5];
gets(d);
puts(d);
getchar();
return 0;
}
//---------------------------------------------------------------------------
که ما میتونیم بیش از 5 کاراکتر تایپ کنیم!!!!
ممنون
Blue Angel
یک شنبه 07 تیر 1388, 14:20 عصر
دلیلش اینه که کامپایلر C موقع اجرا طول آرایه رو کنترل نمی کنه (به خاطر اینکه سرعت اجرای برنامه بالاتر بره) و این وظیفه برنامه نویسه که باید مراقب باشه تا بیشتر از طول آرایه چیزی داخلش نریزه چون ممکنه که روی قسمتهایی از حافظه که به ما ربطی نداره بنویسه و برنامه یا متغییرهای دیگه رو خراب کنه.
Keyhan Clever
یک شنبه 07 تیر 1388, 14:37 عصر
دلیلش اینه که کامپایلر C موقع اجرا طول آرایه رو کنترل نمی کنه (به خاطر اینکه سرعت اجرای برنامه بالاتر بره) و این وظیفه برنامه نویسه که باید مراقب باشه تا بیشتر از طول آرایه چیزی داخلش نریزه چون ممکنه که روی قسمتهایی از حافظه که به ما ربطی نداره بنویسه و برنامه یا متغییرهای دیگه رو خراب کنه.
ولی تا اونجا که من میدونم سیستم عامل به خاطر مسایل امنیتی اجازه دسترسی و یا تعویض متغیرهای خارج از محدوده برنامه رو نمیده
میشه یکی بیشتر کمک کنه ؟
Blue Angel
یک شنبه 07 تیر 1388, 14:52 عصر
ولی تا اونجا که من میدونم سیستم عامل به خاطر مسایل امنیتی اجازه دسترسی و یا تعویض متغیرهای خارج از محدوده برنامه رو نمیده
میشه یکی بیشتر کمک کنه ؟
درسته ولی همون فضایی که به برنامه شما اختصاص می ده رو ممکنه دستکاری کنه.می تونید کتاب طراحی و پیاده سازی زبانهای برنامه سازی رو بخونید .
1485159
یک شنبه 07 تیر 1388, 14:56 عصر
خوب پس بعد از کامپایل هم کنترل نمیکنه؟
قسمت دوم سوال.
ممنون
Nima_NF
یک شنبه 07 تیر 1388, 15:16 عصر
بسیاری از متغیرهایی که تعریف می کنید در واقعیت همانند یک اشاره گر هستند و وقتی از آن ها استفاده می کنید آدرس های آن ها ارسال می شوند و یا کلا جدا از موارد ظاهری در عمل بر روی آدرس ها کار می کنید.
مثلا وقتی خانه آرایه 50 را فراخوانی می کنید یعنی همان آدرس شروع X به علاوه 50 واحد (صرنظر از اینکه کلا چقدر حافظه تخصیص داده اید یا طول آرایه چقدر است)
پس این برنامه نویس هست که باید مواظب آن باشد. اگر بخواهید خارج از حافظه خودتان را دستکاری کنید، آنگاه در هنگام اجرا برنامه شما crash می کند که این موضوع را bug امنیتی "خطرناک" می نامند. چون هکرها می توانند به راحتی از این نقص استفاده کنند و کدهای خود را تزریق کنند و آن ها را توسط برنامه شما اجرا کنند.
به همین خاطر، در سال ها اخیر مایکروسافت شروع کرد به ارائه توابع جایگزین قدیمی که با پسوند _S هستند. (برای نمونه تابع gets_s جایگزین gets است ) به این شکل در یکی از پارامترها شما باید اندازه maximum طول آرایه یا رشته خود را بنویسید تا اشتباها حتی اگر بیش از اندازه حافظه خودتان دریافت کردید، در همانجا متوقف شود و خارج از محدوده حافظه را دستکاری نکند.
1485159
یک شنبه 07 تیر 1388, 15:29 عصر
ولی چنان تابعی در سی بیلدر وجود نداره؟
چطوری میشه این کار رو کنترل کرد؟
Nima_NF
یک شنبه 07 تیر 1388, 16:00 عصر
اگر از C++builder استفاده می کنید باید نسخه های جدید باشد تا این توابع وجود داشته باشند.
در هر حال چند راه برای کنترل به صورت معمول هست،
- یکی اینکه به قدر کافی برای هر رشته حافظه تعریف کنید. توابعی مثل gets اکنون در لیست خطرناک ترین توابع هستند و حتی توصیه می شود اصلا از آن ها استفاده نشود. پس اگر قرار هست همچنان استفاده کنید حداکثر تعداد کارکترهای ممکن در یک خط را ملاک قرار دهید.( پس در مثال شما و کامپایلر قدیمی این راه کار هست)
- یا کلا از روش دیگر برای دریافت از ورودی استفاده کنید.
مثلا fgets ، getline (با stdin برای ورودی یا نام فایل در پارامتر آخر) :
char str[100];
fgets(str, 100, stdin);
در ++C توسط کلاس string و تابع getline و ...
در لینوکس و gcc تابع gets_fixed جایگزین است.
1485159
یک شنبه 07 تیر 1388, 20:00 عصر
وقتی کع تعداد کاراکتر از 100 تا بیشتر باشه از برنامه خارج میشه چرا؟
کد زیر رو برای اینکار نوشتم ولی کار نمیکنه؟
//---------------------------------------------------------------------------
#include <stdio.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
#define index 9
char c[index];//={"sdfsdfsdf"};
int i;
for (i = 0;i<index; ++i)
c[i]=getchar()!=('\n');
for (i = 0; i < index; ++i)
putchar(c[i]);
getchar();
return 0;
}
//---------------------------------------------------------------------------
Nima_NF
یک شنبه 07 تیر 1388, 23:30 عصر
چیزی که مد نظر شماست کدی شبیه زیر هست:
for (i = 0;i<index; ++i)
{
c[i] = getche();
if (c[i]=='\r')
{
putch( '\r' );
putch( '\n' );
}
}
for (i = 0; i < index; ++i)
putchar(c[i]);
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.