سؤال

لقد حاولت إعادة اختراع وظيفة Strcpy C، ولكن عندما أحاول تشغيله، أحصل على هذا الخطأ:

Unhandled exception at 0x00411506 in brainf%ck.exe: 0xC0000005: Access violation writing location 0x00415760.

يحدث الخطأ في *dest = *src; خط. إليك الرمز:

char* strcpy(char* dest, const char* src) {
    char* dest2 = dest;
    while (*src) {
        *dest = *src;
        src++;
        dest++;
    }
    *dest = '\0';
    return dest2;
}

تحرير: واو، كان ذلك سريعا. فيما يلي رمز الاتصال (يتم تعريف Strcpy في MyString.c):

#include "mystring.h"
#include <stdio.h>

int main() {
    char* s = "hello";
    char* t = "abc";
    printf("%s", strcpy(s, t));
    getchar();
    return 0;
}
هل كانت مفيدة؟

المحلول

char* s = "hello";
char* t = "abc";
printf("%s", strcpy(s, t));

وضعت المحول البرمجي المخزن المؤقت وجهة الخاص بك، في ذاكرة للقراءة فقط لأنها ثابتة.

char s[5];
char* t = "abc";
printf("%s", strcpy(s, t));

يجب إصلاح هذه المشكلة. هذا يخصص صفيف الوجهة على المكدس، وهو قابل للكتابة.

نصائح أخرى

المشكلة المحتملة الواضحة هي أن المخزن المؤقت الإخراج الخاص بك لا يحتوي على ذاكرة كافية مخصصة، أو كنت قد مرت ب NULL dest. وبعد (ربما ليس ل src أو كان قد فشل في الخط من قبل.)

يرجى إعطاء برنامج قصير ولكن كامل لإعادة إنتاج المشكلة، ويمكننا التحقق ...

إليك مثال يخرجني عني على Windows:

#include <stdlib.h>

char* strcpy(char* dest, const char* src) {
    char* dest2 = dest;
    while (*src) {
        *dest = *src;
        src++;
        dest++;
    }
    *dest = '\0';
    return dest2;
}

void main() {
    char *d = malloc(3);
    strcpy(d, "hello there this is a longish string");
}

لاحظ أنه في هذه الحالة اضطررت إلى تجاوز الذاكرة المخصصة الفعلية بمبلغ عادل قبل أن أتمكن من استفزاز البرنامج للموت - فقط "Hello" لم يتعطل، على الرغم من أنه بالتأكيد يمكن أن يعتمد على جوانب مختلفة من بيئة التحويل البرمجي والتنفيذ.

STRCPY الخاص بك () على ما يرام. أنت تكتب لذاكرة للقراءة فقط. انظر هذا الوصف هنا.

إذا كتبت هذا، فستكون على ما يرام:

#include "mystring.h"
#include <stdio.h>

int main() {
    char s[] = "hello";
    char t[] = "abc";
    printf("%s", strcpy(s, t));
    getchar();
    return 0;
}

هناك مشكلة في استدعاء روتين Strcpy إعادة اختراع في الروتين الرئيسي، وكلاهما صفيف الأحرف: Char * S = "Hello"؛ char * t = "ABC"؛ سوف تهبط في الذاكرة قراءة القطاع فقط في تجميع الوقت. كما تحاول الكتابة إلى الذاكرة المدببة بموجب S في STRCPY الروتيني، وبذلك يشير إلى موقع في قطاع قراءة فقط، سيتم القبض عليه، وستحصل على استثناء. هذه السلاسل تتم قراءتها فقط!

تأكد من أن dest لها ذاكرة مخصصة قبل الاتصال بهذه الوظيفة.

ربما مشكلة مع المتصل: هل تحقق الوضوح مؤشر؟ هل يشير إلى شيء صالح أو مجرد القمامة؟ إلى جانب ذلك، كان أقل ما يمكنك فعله هو التحقق من مؤشرات فارغة، مثل إذا كان (! Dest ||! المصدر) {/ * القيام بشيء ما، مثل الإرجاع null أو رمي استثناء * /} على إدخال الدالة. الرمز يبدو موافق. ليست آمنة جدا، ولكن حسنا.

هناك العديد من الأخطاء.

  1. لا تخصص المخزن المؤقت عودة يمكن أن يحمل السلسلة المنسوخة.
  2. لا تحقق لمعرفة ما إذا كانت SRC NULL قبل استخدام * SRC
  3. أنت كلاهما لجعل الإجابة في معلمة وإرجاع القيمة. تفعل واحد أو آخر.
  4. يمكنك بسهولة تجاوز المخزن المؤقت DIST.

حظا طيبا وفقك الله.

عند بدء تشغيل التعليمات البرمجية (Gundy، يبدأ تشغيله من الوظيفة الرئيسية). هنا تعني الرمز التسلسل للتقديم وبعد

في التعليمات البرمجية الخاصة بك

char * s = "hello"؛
char * t = "ABC"؛

هذا هو ما تناولته مدخلات من سلوتين مثل هذا.

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

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