Ошибка при получении сегментации: 11, на get_string

#c #cs50

Вопрос:

Я пробую себя get_string в библиотеке CS50. get_string Функция, по-видимому, вызывает ошибку ошибки сегментации. У вас есть какой-нибудь совет?

 #include <cs50.h>
#include <stdio.h>
int main (void) {
    string answer = get_string("What's your name? ");
    printf("Hello, %s", answer);
}
 

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

1. Я не думаю, что этот код может привести к ошибке сегментации

2. @EugeneSh. это вывод терминала: Macbook-Pro:Лязг MACBOOK$ сделать привет cc привет.c -o привет Macbook-Pro:Лязг MACBOOK$ ./Ошибка сегментации hello: 11

3. Да, это возможно, строка (которая есть char* ) может быть НУЛЕВОЙ, Документация рекомендует специально проверять это cs50.readthedocs.io/libraries/cs50/c

4. @JackWhite, найденный в документах «Возвращает строку чтения в виде строки. Если пользователь вводит только окончание строки, возвращает «», а не NULL. Возвращает значение NULL при ошибке или вообще без ввода (т. Е. Просто EOF).» . Звучит маловероятно, если только ОП намеренно не снабжает его EOF…Я все еще думаю, что ОП на самом деле не запускает этот код.

5. Должно быть в том же каталоге make , в котором вы работаете

Ответ №1:

Ладно, после некоторых поисков я думаю, что нашел виновника. И, по-видимому, это не то место, где мы искали.

Mac OS X , по-видимому, имеет встроенный символ с именем get_string , поэтому он скомпилирован без библиотеки и продолжает сбоить.

К этой проблеме может быть несколько подходов

Скомпилируйте cs50.c в свой двоичный файл

Этот метод был упомянут здесь. Я не тестировал его, но, как сообщается, он работает.

Скомпилируйте свой код следующим образом:

 clang -ggdb3 -O0 -std=c99 hello.c ../../../github.com/cs50/lib50-c/src/cs50.c -o hello
 

где ../../../github.com/cs50/lib50-c/src/cs50.c путь к файлу cs50.c , который находится в подкаталоге src cs50 исходного кода библиотеки — если на вашем компьютере он отличается, пожалуйста, используйте правильный путь.

Вы также можете просто скопировать cs50.c файл в каталог с hello.c помощью и просто указать cs50.c путь без

Пожалуйста, обратите внимание, что вы должны указать этот файл после вашего, иначе он не будет работать!

На самом деле, в таком случае этого должно быть достаточно:

 cc hello.c cs50.c -std=c99 -o hello
 

С этого момента вам нужно будет включать cs50.c после себя каждый раз, когда вы будете компилировать свой код.

Переименуйте функцию

Поскольку у меня нет Mac, я не могу ничего протестировать, поэтому перечислю единственный способ, который наверняка сработает — переименовать функцию get_string в get_string2 . Это не очень хорошее решение, но это все, что я могу вам сейчас дать.

Пожалуйста, используйте это только в том случае, если первый подход не работает.

  1. перейдите в каталог, из которого вы установили cs50
  2. удалите его, выполнив команду sudo make uninstall
  3. откройте файл cs50.h из подкаталога src в любом текстовом редакторе
  4. найдите и замените все вхождения get_string с get_string2 (у меня был один в строке 108 и два в строке 109)
  5. сохраните и закройте файл
  6. откройте файл cs50.c из подкаталога src в любом текстовом редакторе
  7. найдите и замените все вхождения get_string с get_string2 (их очень много)
  8. сохраните и закройте файл
  9. вернитесь в исходный каталог сборки cs50 и выполните команды:
 make clean
make 
sudo make install
 
  1. перейдите в каталог с hello.c
  2. отредактируйте hello.c и замените get_string на get_string2
  3. скомпилируйте cc hello.c -lcs50 -o hello и запустите с помощью ./hello

Вам также может потребоваться выполнить следующие команды перед компиляцией и выполнением:

 export LIBRARY_PATH=/usr/local/lib
export C_INCLUDE_PATH=/usr/local/include
export LD_LIBRARY_PATH=/usr/local/lib
 
  1. С этого момента вам нужно будет менять каждое использование get_string в вашем коде на get_string2
  2. не забудьте изменить обратно при отправке кода.

В качестве альтернативы вы могли бы поместить что-то подобное в начале своих программ:

 #ifndef get_string2
#define get_string2 get_string
#endif
 

…это означает, что для всех остальных, кто запускает ваш код (и не имеет макроса get_string2 ), это будет то get_string2 же get_string самое, что и — поэтому ваш код будет работать как с измененной, так и с неизмененной библиотекой.


Опять же, это явно не лучший способ сделать это, но, поскольку я не могу его проверить, это лучшее, что я мог придумать. Извините.

Если кто — то другой предложит лучший способ-это было бы здорово

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

1. -std=c99 должно предотвратить определение любых нестандартных символов-если это действительно проблема, о ней следует сообщить как об ошибке компилятора