كيفية استخدام strnlen بأمان؟

1

أحاول أن أفهم ما هي الطريقة الصحيحة للاستخدام strnlen بحيث يتم استخدامه بأمان حتى مع مراعاة حالات الحافة.

مثل وجود سلسلة غير منتهية بقيمة خالية كإدخال.

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

int main()
{
    void* data = malloc(5);

    size_t len = strnlen((const char*)data, 10);
    printf("len = %zu\n", len);

    return 0;
}

إذا كنت أتوقع سلسلة من الحجم الأقصى 10 ، ولكن السلسلة لا تحتوي على حرف فارغ ضمن تلك الأحرف العشرة strnlen سيتم قراءة خارج حدود البايت (قد يشير مؤشر الإدخال إلى كومة البيانات المخصصة). هل هذا السلوك غير محدد؟ إذا كانت الإجابة بنعم ، فهل هناك طريقة للاستخدام بأمان strnlen لحساب طول السلسلة التي تأخذ في الاعتبار هذا النوع من السيناريو ولا تؤدي إلى سلوك غير محدد؟

3 الاجابة

5
افضل جواب

لكي تستخدم strnlen بأمان أنت بحاجة إلى

  1. تتبع حجم المخزن المؤقت للإدخال بنفسك (5 في حالتك) وقم بتمرير ذلك كمعلمة ثانية ، وليس رقمًا أكبر من ذلك.

  2. تأكد من أن مؤشر الإدخال ليس كذلك NULL .

  3. تأكد من عدم كتابة مؤشر ترابط آخر إلى المخزن المؤقت.

من الناحية الرسمية ، لا تحتاج إلى تهيئة محتويات المخزن المؤقت ، حيث تقرأ الوظيفة من الناحية المفاهيمية المخزن المؤقت كما لو كانت char أنواع.

:مؤلف
1
افضل جواب

من المرجح أن يستدعي هذا الرمز سلوكًا غير محدد .

تم إرجاع البايت بواسطة malloc لها قيم غير محددة. إذا لم يكن هناك بايت بايت في 5 بايت التي يتم إرجاعها ، ثم strnlen ستقرأ هذه البايت بعد تمريرها بحد أقصى 10 بايت ، والقراءة بعد نهاية الذاكرة المخصصة تستدعي سلوكًا غير محدد.

قراءة البايت التي تم إرجاعها لا يجب أن تكون غير محددة. في حين أن القيم غير المحددة يمكن أن تحمل تمثيل فخ ، strnlen يقرأ البايت باستخدام أ char * ، وأنواع الأحرف ليس لها تمثيل اعتراض ، لذا فإن القيم غير محددة فقط وقراءتها آمنة.

إذا انتقلت القيمة إلى strnlen ليس أكبر من حجم الذاكرة المخصصة ، ثم استخدامه آمن.

:مؤلف
0

نظرًا لأن الطول الفعلي للبيانات هو 5 ، وعلى الأرجح ليس لديك "\ 0" هناك ، فسيبدأ في قراءة الذاكرة غير المخصصة (بدءًا من البيانات [5]) ، والتي قد تكون غير سارة بعض الشيء.

:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام