#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], и это все равно не работает