2016-01-18 3 views
2

У меня есть небольшой фрагмент кода, в котором выводятся слова, разделенные новой строкой, и выводятся из строя (слово, 1) в качестве вывода. Вот код:Отладка моего токенизатора строки с помощью gdb

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, char *argv[]) { 
    char *str1, *str2, *token; 
    char *saveptr1; 
    char buffer[100]; 
    while (fgets(buffer, sizeof(buffer), stdin) != NULL) { 
     token = strtok_r(buffer, '\n', &saveptr1); 
     printf("(%s,1)\n", token); 
    } 
    exit(EXIT_SUCCESS); 
} 

Этот код работает правильно и обеспечивает ожидаемый выход. Однако, когда я перехожу через код с помощью gdb, в строке 9 появляется следующая ошибка: строка strtok_r.

Программный сигнал SIGSEGV, ошибка сегментации. strtok_r() at ../sysdeps/x86_64/strtok.S:101 101 ../sysdeps/x86_64/strtok.S: Нет такого файла или каталога.

Это недоумение. Я даже не «вступаю» в линию strtok_r, я просто «рядом», то есть перешагиваю. Почему он бросает эту ошибку во время GDB? Я беспокоюсь, потому что у меня есть реальная, большая программа, которую я не могу отлаживать из-за этой проблемы. Фактически, для большинства всех строковых функций (strncmp, strncpy) эта проблема возникает.

Редактировать: компилятор предупреждал о назначении, создавая указатель из целого числа без трансляции в этой строке, я должен был бы поставить 2 и 2 вместе.

+3

'' \ n'' -> '' \ n "' – BLUEPIXY

+0

Это похоже на это .. Это очень удивительно ... Я, хотя escape-последовательность \ n все еще считается только символом ... – nirvanaswap

+0

включите предупреждения -Wall. Это спасет вас. –

ответ

1

Вы передаете символьный литерал вместо строкового литерала до strtok_r, функция библиотеки strtok_r вылетает из строя, пытаясь разыменовать неверный указатель.

GDB пытается отобразить исходный код сборки для strtok_r, расположенный в ../sysdeps/x86_64/strtok.S (он знает это из стандартной информации об отладке библиотеки C), но не может найти исходный файл в этом месте.

Вы должны, конечно, исправить код так:

token = strtok_r(buffer, "\n", &saveptr1); 

Это хорошая идея, чтобы включить как можно больше предупреждения как можно из компилятора с -Wall -Wextra -Werror и исправить код, пока компилятор не обнаруживает подозрительные код больше.

На самом деле вы упомянули использование strncpy: эта функция очень ошибка склонна. Он не делает то, что думает большинство людей, это никогда не будет правильным инструментом. Прочтите документацию и тщательно проверьте, правильно ли вы используете его, и если в этих местах нет лучшей альтернативы.

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