2014-01-31 2 views
0

Я новичок в C, поэтому извиняюсь, если ответ очевиден, я искал в другом месте.printf вызывает segfault с getlogin()

библиотеки я в том числе, являются:

#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <fcntl.h> 
#include <sys/stat.h> 

код, который не удается это:

char *USER = getlogin(); 
    char CWD[128]; 

    if (USER == NULL) 
     printf("cry\n"); 

    getcwd(CWD, sizeof(CWD)); 
    printf("this prints\n"); 
    printf(USER); 
    printf("this does not\n"); 
    printf("%[email protected]:%s> ", USER, CWD); 

крик не печатает, так что должно означать, что getlogin успешно. segfault вызван printf (USER); далее

тестирование показывает, что феллинг блок печатает полностью

printf("this prints\n"); 
    printf(USER); 
    printf("this prints\n"); 

но феллинг блок будет печатать эти отпечатки конец затем сегментации, не показывая USER

printf("this prints\n"); 
    printf(USER); 

EDIT:

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

Thanks

+0

Возможно, он находится в процессе печати 'cry', но ему не хватает времени, прежде чем он будет неисправен. Добавьте точку останова (или что-то), чтобы проверить, что блок 'if' не вводится. –

+0

попытаться добавить: еще printf ("% s \ n", USER); –

+0

printf (CWD) работает, если я помещаю его непосредственно перед printf ("% s @ myshell:% s>", USER, CWD); – d0m1n1c

ответ

2

Необходимо проверить возвращаемое значение getcwd. По словам мужчины странице getcwd:

Если длина абсолютный путь текущей рабочей каталога, включая завершающий нулевой байт, превышает размер байт, NULL возвращается, и ERRNO установлен в ERANGE; приложение должно проверить эту ошибку и при необходимости назначить больший буфер.

+0

print (CWD) печатает отлично, если я помещаю его перед printf ("% s @ myshell:% s>", USER, CWD), но ничего после printf ("% s @ myshell:% s>", USER, CWD); будет печатать – d0m1n1c

+0

Путь не был таким большим, но я увеличил размер CWD до 1024, чтобы быть уверенным, и он все еще терпит неудачу. – d0m1n1c

0

Если USER имеет нулевое значение, printf будет разыменования нулевого указателя, что неопределенное поведение. Компилятор не обязан делать что-то, что имеет смысл, когда происходит неопределенное поведение, поэтому ему не разрешается печатать «крик», когда USER имеет значение NULL. Вы хотите избежать неопределенного поведения.

Что-то еще, что может привести к вашему результату, заключается в том, что данные, отправленные на stdout, обычно буферизуются. Если программа сработает до сброса данных из буфера, данные будут потеряны вместо печати.

0

Так вот как Printf работает ...

  1. он должен читать в строке формата.
  2. он должен захватывать значения из стека, чтобы выполнять спецификаторы формата, форматировать их и выводить их.

примеры вещей, которые могут вызвать это ...

char stringOfTest[5] = {'1','2','3','4','5'}; 

или

char * stringOfTest = "here are some formats that will be unsatisfied: %d%f%i%s%x"; 

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

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

Третий способ также во втором примере ... если у вас есть% s, это приведет к разыменованию указателя ... так что может также произойти сбой.

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