2013-08-14 3 views
0

Это код ядро ​​Linux использует, чтобы лишить начальные и конечные пробелы в строке:С строка полосы пробельные генерирует ошибку сегментации (ядро сбрасывали)

char *strstrip(char *s) 
{ 
     size_t size; 
     char *end; 

     size = strlen(s); 

     if (!size) 
       return s; 

     end = s + size - 1; 
     while (end >= s && isspace(*end)) 
       end--; 
     *(end + 1) = '\0'; 

     while (*s && isspace(*s)) 
       s++; 

     return s; 
} 

Здесь я использовать его в качестве такового:

int main(void){ 

    /* strip test*/ 
    char buffer2[60]; 
    char* testy2 = buffer2; 
    testy2 = "  THING!  "; 
    printf("The stripped string: \"%s\"\n",strstrip(testy2)); 
    return 0; 
} 

программа компилируется нормально, но при выполнении в нем говорится:

Segmentation fault (core dumped)

Почему это происходит?

ответ

2
testy2 = "  THING!  "; 

testy2 чтобы указать на строковый литерал. Это может существовать в постоянной памяти, поэтому запись не может быть записана на strstrip.

Вам нужно либо выделить память для testy2

const char* s = "  THING!  "; 
testy2 = malloc(strlen(s)+1); 
strcpy(testy2, s); 
.... 
free(testy2); 

или, проще, просто инициализирует buffer2 строки вы хотите манипулировать

char buffer2[] = "  THING!  "; 
printf("The stripped string: \"%s\"\n",strstrip(buffer2 
+0

Спасибо. Он работает сейчас. – turnt

2

Строки литерала в коде, как правило, помещенный компилятор в раздел только для чтения в памяти вашей программы. Когда вы назначаете testy2 = " THING! ";, вы устанавливаете testy2, чтобы указать на строковый литерал в статической памяти «только для чтения». Затем, когда вы вызываете strstrip() для изменения этой памяти, вы получаете SIGSEGV или что-то другое, что ваша платформа вызывает его, в момент, когда strstrip() пытается записать nul char ('\0'), потому что вы не можете записать в память, чьи атрибуты установлены в " только для чтения». Чтобы получить копию этого строкового литерала, который вы можете изменить, вы можете использовать strcpy(), чтобы сделать его копию, и вызвать strstrip() на эту копию. Конечно, чтобы сделать копию, вы должны скопировать его в память, которую вы можете получить от malloc(strlen(testy2)+1) или new char[strlen(testy2)+1], или, как вы это делали в своем первоначальном посте, создав локальное выделение.

Следует отметить, что strstrip(): 1) возвращает указатель, который может отличаться от указателя пройденного, и 2) может изменять строку в памяти, переданной ей. В вашем примере вы теряете возвращаемый указатель, потому что вы его не присвоили никому ... что не так уж плохо, потому что вы можете вернуть тот же адрес указателя, просто позвонив strstrip() на исходный указатель, но это было бы немного неэффективно, если бы вам понадобилась обрезанная строка более одного раза. Но будьте осторожны здесь ... если вы использовали malloc() или new для динамического выделения пространства для вашей копии строкового литерала (и назначили возвращенный адрес указателю, скажем testy2), то не назначайте возврат strstrip() к этому указателю, иначе вы не сможете использовать указатель, чтобы освободить динамически выделенную память! Когда вы звоните free() или delete, вам необходимо передать исходный указатель, который вы получили от malloc() или new, а не указатель, который вы получили от strstrip().

3

Во время присвоения testy2 (testy2 = " THING! ";) вы указываете на статику только для чтения память.

Но в вашей функции strstrip() вы пытаетесь ее изменить.

Вы можете решить путем выделения testy2 динамически с помощью malloc, например:

testy2 = malloc(sizeof("  THING!  ") + 1); 
strcpy(testy2, s); 

// But don't forget to free the memory at the end ! 
free(testy2); 
2

Линия

testy2 = "  THING!  "; 

не делать то, что вы думаете, что он делает. Он не копирует " THING! " в buffer2. Это просто указание указателя testy2 на строковый литерал " THING! ". Затем, когда вы вызываете функцию strstrip(), функция пытается изменить строковый литерал, что является неопределенным поведением. Отсюда и погрешность сегментации.

Вы, вероятно, хотите использовать strcpy() вместо оператора присваивания:

strcpy (testy2, "  THING!  "); 

 Смежные вопросы

  • Нет связанных вопросов^_^