ошибка сегментации в C, не могу определить причину

#c #pointers #segmentation-fault

#c #указатели #ошибка сегментации

Вопрос:

Приведенная ниже функция должна изменить на верхний регистр все вхождения второй строки в первой. Когда он соответствует первой букве, он должен указать p на его позицию в первой строке, а затем проверить оставшуюся часть строки соответствия. Если происходит совпадение, он заменяет каждый символ его версией в верхнем регистре. Когда я пытаюсь получить доступ к значениям, на которые указывает p, я получаю «ошибку сегментации», я знаю, что с этой программой много чего не так: я мог бы просто сохранить позицию первого символа в i и использовать i j в качестве индекса для первой строки. Я также не проверяю, содержит ли вторая строка только буквы. В любом случае, я действительно хочу знать, что не так с использованием указателей в этом конкретном случае, даже если я могу переписать его лучшую версию.

 char *matchToUp(char *s, char *match)
{
    int i = 0, j=0;
    char *p = s;

    while (s[i] != '')
    {
        while(s[i]!= match[0] amp;amp; s[i]!= '')
        {

            i  ;
        }
        printf("%d", i);
        p = amp;s[i];
        while (match[j] != '' amp;amp;p[j] == match[j])
        {
            j  ;
        }
        if(match[j] == '')
        {
            printf("%d", j);
            while(j >= 0)
            {
                p[j] = (char) toupper((unsigned int) p[j]);
                j--;
                i  ;

            }
        }
        else
        {
            j=0;
            i  ;

        }
    }


    return s;
}
  

Комментарии:

1. Источник проблемы находится в вызывающем (ну, и в этой функции тоже, поскольку она не проверяет правильность переданных ей данных. )

2. Запустите его через valgrind и / или gdb и посмотрите, что вы получите.

3. char * p; p = matchToUp(«abcde», «abc»); Я должен проверить данные на вменяемость, это верно, но я добавил «de» на всякий случай, и проблема не в том, что адрес выходит за рамки. Я использую Code::Blocks, делает ликод работает вне ide?

4. Итак, вы пытаетесь изменить строковый литерал, доступный только для чтения, путем присвоения p[..] .

5. Так вот в чем проблема! Я забыл, что строковые литералы доступны только для чтения. Что мне делать? должен ли я выделить память для копии первой строки на всякий случай и вернуть указатель на измененную строку?

Ответ №1:

Ошибки сегментации возникают, когда функция (или процесс) пытается получить доступ к памяти, которая находится вне ее границ. В этом случае похоже, что вы передаете указатель в функцию ( *s ). Если вызывающая сторона не выделила место для этой строки в куче, используя malloc , то переменная по умолчанию находится в stack вызывающей функции. Каждая функция получает свою собственную stack frame , доступ к памяти за пределами вашего фрейма стека вызовет segmentation fault . Поэтому при переходе s* в эту функцию вы (потенциально, я должен был бы видеть вызывающего, чтобы знать наверняка :)) передаете указатель на массив символов, который не является частью вашего фрейма стека. Таким образом, вы получаете a segmentation fault , потому что пытаетесь получить доступ к чему-либо по адресу s*[j] , но этой функции не разрешен доступ к этому пространству.

Комментарии:

1. Я передал строковый литерал в качестве аргумента и попытался изменить его, не выделяя память.

2. ах да, это тоже сработало бы 🙂

Ответ №2:

Вы начинаете выполнять действия с одним элементом, в вашем коде p[j] указывает на первый вызов через один после совпадения.

Комментарии:

1. да, это правда, но я исправил это, протестировав j> 0 и уменьшив j перед доступом к p[j], и это все равно не работает