ج:strncpy أحرف أكثر من المخصصة ثم الطباعة... إخراج غير متوقع؟

StackOverflow https://stackoverflow.com//questions/9613450

سؤال

في بعض نماذج التعليمات البرمجية التي قدمها الأستاذ:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
  char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  printf( "%s\n", alpha );
  printf( "%c\n", alpha[8] );
  alpha[8] = 'Z';   /* segmentation fault if alpha is declared statically! */

  printf( "%d\n", sizeof( alpha ) );
  printf( "%d\n", strlen( alpha ) );

  char x[10];
  strncpy( x, alpha, 26 );
   /* strncpy() will NOT copy or append a '\0' */
  printf( "%s\n", x );

  return EXIT_SUCCESS;
}

عند التجميع والتشغيل لأول مرة، تنقسم أخطاء البرنامج بسبب ما أراه في بضع دقائق من البحث في Google، وهي آلية حماية دول مجلس التعاون الخليجي ضد تجاوزات المخزن المؤقت (التي يتم تشغيلها بواسطة printf( "%s\n", x ); حيث تم ملء x بـ 26 بايت من ألفا).هذا وأعتقد أنني أفهم.

ومع ذلك، عند تعطيل آلية الحماية باستخدام gcc -fno-stack-protector، فإن الإخراج الذي أراه هو:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
I
27
26
ABCDEFGHZJKLMNOPQRSTUVWXYZKLMNOPQRSTUVWXYZ

اعتقدت أنه بما أن strncpy لا ينهي السلسلة، فذلك متى X تمت طباعته وقد يطبع القيمة الكاملة لـ alpha- ولكن في الواقع، يتم طباعة كل شيء alpha, ، ثم المزيد alpha!

هل يمكن لأي شخص تقديم بعض البصيرة هنا؟

هل كانت مفيدة؟

المحلول

مع هذا الرمز: giveacodicetagpre.

أنت نسخ 26 بايت من البيانات إلى صفيف 10 بايت، مما يعني أنك تقوم بالكتابة فوق 16 بايت من أي ذاكرة حدثت أن تكون مجاورة ل "X".إنها هذه الحالة تبدو وكأنها مجاورة "X" كانت "ألفا"، لذلك تقوم بإلقاء الضوء على جزء من صفيفك الأولي

عند "printf" x، فإنه يبقي الطباعة حتى يضرب بايت فارغة، لذلك يطبع جميع البايتات 26 التي قمت بنسخها، بالإضافة إلى أي شيء آخر في الذاكرة (المحتويات الباقية من "Alpha") حتى البايت البايت Null التالي.

نصائح أخرى

أنت محظوظ فقط.الكتابة خارج حدود المصفوفة تؤدي إلى سلوك غير محدد.

السلوك غير المحدد يعني أن أي سلوك ممكن، ولا يلزم دائمًا أن يؤدي إلى خطأ تجزئة، بل يعني ببساطة أن البرنامج غير صالح وقد يظهر أي سلوك.

نعم، قد يبدو أن برنامجك يعمل كما هو مطلوب في بعض الأحيان، ولكنه لا يزال برنامجًا غير سليم وفقًا للمعايير.

giveacodicetagpre.

إلى strncpy، فأنت تمر، 26 كقيمة n، لذلك نسخ 26 حرفا، ولكن عند الطباعة باستخدام PrintF، سيحاول PrintF البحث عن "\ 0" كحرف إنهاء السلسلة.في هذه الحالة، يحدث ذلك بطريقة أو بأخرى "\ 0" موجود بعد "klmnopqrstuvwxyz".

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

السؤال هو عن تخطيط الذاكرة.
في هذا البرنامج، "Alpha" هو فقط وراء "X".لذلك عند الاتصال giveacodicetagpre.

يتم تعديل بيانات ألفا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top