رفتن به مطلب
مرجع رسمی سی‌پلاس‌پلاس ایران

سوال

در برسی کدهای برنامه ای که قبلا نوشته شده بود و ظاهرا در حال حاضر بدرستی کار می کند به صحت عمل تابع مشابه doXOR شک کردم. متن doXOR و روش استفاده شده از آن را در زیر اضافه می کنم. لازم به ذکر است فقط به روش زیر استفاده می شود.

char *doXOR(char *cData1, char * cData2)
{
	char cData[256];
	//

	for (int i = 0; i < 256; ++i)
	{
		cData[i] =cData1[i] ^ cData2[i];
	}
	//
	cData[255] = 0;

	return cData;
}

void usedoXOR()
{
	char cData1[256];
	char cData2[256];
	char cData3[256];
	//
	memset(cData1, 0, sizeof(cData1));
	memset(cData2, 0, sizeof(cData2));
	memset(cData3, 0, sizeof(cData3));

	strcpy(cData1, "In C, the following 6 operators are bitwise operators (work at bit-level)");
	strcpy(cData2, "Typical usage of a right shift operator in C can be seen from the following code.");

	strcpy(cData3, doXOR(cData1, cData2));
}

 همانطور که میبینید در doXOR در انتها آدرس cData که یک متغییر محلی است برگشت داده می شود و من انتظار دارم قبل از خارج شدن از doXOR حافظه های اختصاص داده شده آزاد گردد لذا بهد از خروج از doXOR آدرس cData معتبر نخواهد بود اگر چه همچنان حاوی اطلاعات قبلی است.

نظر شما چیست.

1 - نوشتن به این شکل مشکل دارد یا نه؟ 

2 - اگر مشکلی دارد آیا نحوه استفاده ما در usedoXOR  از خروجی doXOR به عنوان ورودی strcpy موجب شده تا این مشکل خود را نشان ندهد؟

3 -  آیا نوع کمپایلر و سیستم عامل میتوانند در پاسخ به دو سوال بالا تاثیرگذار باشند.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

3 پاسخ به این سوال تا کنون داده شده است

پست های پیشنهاد شده

  • 0
ارسال شده در (ویرایش شده)

درود بر شما؛

در در 3 مهر 1398 در 09:20، kambiz behnia گفته است :

1 - نوشتن به این شکل مشکل دارد یا نه؟ 

بله مشکل دارد، همانطوری که خودتان هم گفتید دارید آدرس یک متغیر محلی را از تابع بر می‌گردانید که این اخطار را هم از سمت کامپایلر هنگام کامپایل آن تابع دریافت می‌کنید ‌:

$ warning: function returns address of local variable

و برنامهٔ شما هم به احتمال زیاد Segmentation Falut داده و از بین می‌رود.

 

در در 3 مهر 1398 در 09:20، kambiz behnia گفته است :

2 - اگر مشکلی دارد آیا نحوه استفاده ما در usedoXOR  از خروجی doXOR به عنوان ورودی strcpy موجب شده تا این مشکل خود را نشان ندهد؟

 

در در 3 مهر 1398 در 09:20، kambiz behnia گفته است :

3 -  آیا نوع کمپایلر و سیستم عامل میتوانند در پاسخ به دو سوال بالا تاثیرگذار باشند.

برنامهٔ شما ممکن است که خروجی درستی نداشته باشد، چراکه دارید از یک حافظه‌ای داده را می‌خوانید که اصلاً وجود ندارد (حافظه آزاد شده است).

  • در کامپایلر MSVC2017 و سیستم‌عامل Windows 7 64bit کد را برای شما کامپایل و بدون مشکل اجرا می‌کند امّا خروجی درستی ندارید.
  • در کامپایلر MinGW و سیستم‌عامل Windows 7 64bit کد را کامپایل و اخطاری که در بالا اشاره کرده‌ام را داده و در هنگام اجرا برنامه با Segmentation Fault رو به رو می‌شود.
  • کامپایلرهای GCC و‌ Clang در سیستم‌عامل ArchLinux اخطار بالا را داده و همانند MinGW عمل می‌کند.
  • کامپایلر TCC در سیستم‌عامل ArchLinux نیز همانند MSVC2017 عمل می‌کند.

 

بهتر است که تابع را به این شکل بازنویسی کنید :

char* doXOR(char* cData1, char* cData2)
{
	char* cData = malloc(256);
  	assert(cData);
	for (int i = 0; i < 255; ++i)
		{ cData[i] =cData1[i] ^ cData2[i]; }
	cData[255] = '\0';
	return cData;
}

و همچنین موقع استفاده :

int main (void)
{
	/* ... */
	char* tmp = doXOR(cData1, cData2);
	strcpy(cData3, tmp);
	printf("%s\n", cData3);
	free(tmp); tmp = NULL;
  
	return EXIT_SUCCESS;
}

 

ویرایش شده در توسط قاسم رمضانی منش
تصحیح خطای نمونه کد.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
  • 0
ارسال شده در (ویرایش شده)
در 3 ساعت قبل، فرهاد شیری گفته است :

دلیل بهتر بودن کد خودتون را هم بیان کنید؟

علیکم‌السلام و درود بر شما؛ راستش با توضیحاتی که دادید خیلی گیج شدم و منتظرم که وقتی باشد تا کتابی که پیشنهاد دادید را بخوانم، چون کدهایی که دوستمان ارسال کرده‌اند درواقع برای من اصلاً جواب نداد و Segmentation Fault داده. و تا به چیزی که امروز من یادگرفته‌ام می‌دانم که آدرس یک متغیر local را نباید از تابع برگرداند و این دقیقاً کاری هست که در کد انجام شده و کاری که من کرده‌ام و دلیلی که بهتر دیده‌ام این بوده که حافظه‌ای در Heap  گرفته‌ام و آدرس آن را برگرداندم و این عمل بدون Segmentation Fault کار خود را انجام میدهد. امّا همینطوری که گفتم :

در در 4 مهر 1398 در 11:13، قاسم رمضانی منش گفته است :
  • در کامپایلر MSVC2017 و سیستم‌عامل Windows 7 64bit کد را برای شما کامپایل و بدون مشکل اجرا می‌کند امّا خروجی درستی ندارید.
  • در کامپایلر MinGW و سیستم‌عامل Windows 7 64bit کد را کامپایل و اخطاری که در بالا اشاره کرده‌ام را داده و در هنگام اجرا برنامه با Segmentation Fault رو به رو می‌شود.
  • کامپایلرهای GCC و‌ Clang در سیستم‌عامل ArchLinux اخطار بالا را داده و همانند MinGW عمل می‌کند.
  • کامپایلر TCC در سیستم‌عامل ArchLinux نیز همانند MSVC2017 عمل می‌کند.

اصلاً رفتار کد به درستی مشخص نبود و با توضیحات شما هم چیزی متوجه نشدم.

ویرایش شده در توسط قاسم رمضانی منش
اصلاح غلط کلمات.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
  • 0
در 20 ساعت قبل، فرهاد شیری گفته است :

کدهای شما درست است و قابل اجرا هستند! به همین دلیل هم بدرستی کار میکنند!

از بابت توضیح در پاسخ اول متشکرم  سعی میکنم کتابی را که معرفی کرده بودید حتما مطالعه کنم. احساس میکنم پاسخ دوم با پاسخ اول در تناقض باشد و بطور کلی استفاده به این شکل درست نباشد. خودم فکر میکنم چون مقدار بازگشتی تابع را مستقیما به دستور copy ارسال کرده ایم و احتمالا در آن از حافظه استک استفاده نشده در عمل دوچار مشکل نشده ایم ولی چنانچه اگر به صورت دیگری استفاده کنیم حتما مشکل حافظه خواهیم داشت مثلا خودم دوباره strcpy را بازنویسی کنم بطوریکه در ابتدا آن اقدام به تعریف یک آرایه 256 تای از char نمودم اگر چه در بدنه آن هیچ استفاده ای از آن نکردم ولی موجب خراب شده داده های مورد نظر من شد و تابع بهصورت درست عمل نکرد و وقتی آن حاظه را از استک نگرفت برنامه کار مورد نظر من را انجام داد.

یکی از دوستان برای چنین مواردی اصطلاح جالبی داشت "برنامه به غلط درست کار میکند."

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

به گفتگو ملحق شوید

شما همین الآن می‌توانید مطلبی را ارسال و بعداً ثبت‌نام کنید. اگر حساب کاربری دارید، و با حساب کاربری خود مطلب ارسال کنید.
نکته: مطلب شما قبل از انتشار نیاز به بازبینی توسط میانجی‌گر‌ها دارد.

مهمان
پاسخ به این سوال ...

×   شما در حال چسباندن محتوایی با قالب بندی هستید.   حذف قالب بندی

  تنها استفاده از ۷۵ اموجی مجاز می باشد.

×   لینک شما به صورت اتوماتیک جای گذاری شد.   نمایش به عنوان یک لینک به جای

×   محتوای قبلی شما بازگردانی شد.   پاک کردن محتوای ویرایشگر

×   شما مستقیما نمی توانید تصویر خود را قرار دهید. یا آن را اینجا بارگذاری کنید یا از یک URL قرار دهید.


  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×
×
  • جدید...