سؤال

segfaults الكود الخاص بي ولا أعرف السبب.

 1  #include <stdio.h>
 2
 3  void overwrite(char str[], char x) {
 4    int i;
 5    for (i = 0; str[i] != '\0'; i++)
 6      str[i] = x;
 7  }
 8
 9  int main(void) {
10    char *s = "abcde";
11    char x = 'X';
12    overwrite(s, x);
13    printf("%s\n", s);
14    return 0;
15  }

أخبرني مصحح أخطاء gdb أن هذه المشكلة موجودة في السطر 6، حيث أريد تخزين char في سلسلة c (إذا كنت أستخدم إلغاء مرجعية مؤشر lvalue، فهي نفس المشكلة.) وهذا ما يقوله:

(gdb) run
Starting program: /tmp/x/x 

Breakpoint 1, overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:5
5         for (i = 0; str[i] != '\0'; i++)
(gdb) s
6           str[i] = x;
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x080483e3 in overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:6
6           str[i] = x;
(gdb) q

أنا أتعلم من كتاب K&R-C وهذا مثال مبسط من الفصل 2.8 (وظيفة الإزالة).ليس لدي أي فكرة أين هي المشكلة.

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

المحلول

ولأن شار * ق = "ABCDE". يخلق سلسلة في ذاكرة للقراءة فقط. محاولة

char s[] = "abcde";

وتحرير: التفسير: شار * هو المؤشر، ويتم إنشاء "ABCDE" في ذاكرة للقراءة فقط -> غير قابل للتغيير

وشار [] غير مجموعة، والتي يتم تخزينها كليا على المكدس وتهيئة من الذاكرة، وذلك هو قابلة للتغيير

نصائح أخرى

عند تحديد مؤشر إلى أ سلسلة حرفية, ، أعلن ذلك const char *.

const char *s = "abcde";

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

const char *s = "abcde";
char t[] = "fghij";
char x = 'X';

overwrite(s, x); /* oops */
overwrite(t, x); /* ok */

وليس الاختلاف، ولكن فقط لتوضيح: النظر في ما يمكن أن يحدث إذا سمح للمترجم هذا. هل يمكن أن يكتب:

char *s1="abcde";
char *s2="abcde";
s1[0]='x';
puts(s1);
puts(s2);

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

xbcde
xbcde

والذي هو على الارجح وليس ما كنت تريد. وهذا سيكون غامض لا سيما إذا كانت حرفية اثنين في أجزاء متباعدة من البرنامج.

وجرب:

#include <iostream>
#include <cstring>

using namespace std;

void overwrite(char[], char);

int main(void)
{
        char *s = strdup("abcde");
        char X = 'X';
        overwrite(s, X);
        cout << s << endl;

        if(s!=NULL)
                delete [] s;

        return 0;
}

void overwrite(char str[], char x)
{
        for(int i=0; str[i]!='\0'; i++)
                str[i] = x;
}

وتخميني هو تعريف المعلمة حيث يمكنك تحديد نوع باعتباره مجموعة من حرف. في حين يتم تمرير مؤشر إلى شار

هل يمكن أن حاول تغيير السطر الأول لهذه:

 void overwrite(char *str, char x) {

وهناك مجموعة شار ومؤشر شار ليست غويا نفسه.

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