2016-02-28 4 views
1

Я думаю, что у меня все исправлено. Я допустил ошибку приращения переменной окружения вместо того, чтобы рассматривать ее как массив и итерации по ней. Следующее - это то, что у меня есть сейчас, и должно быть хорошо идти.Сегментация Неисправность при использовании malloc

extern char **environ; 

int main(int argc, char *argv[]) { 
    // determine number of environment variables 
    int n = 0; 
    char *c = NULL; 
    while ((c = environ[n++]) != NULL) { 
     printf("%s\n", c); 
    } 
    printf("%s\n%d\n\n", c, n); 

    // allocate array to store character pointers to environment array 
    char **new_c; 
    printf("This prints\n"); 
    if ((new_c = malloc(n * sizeof(*c))) == NULL) { 
     printf("Error\n"); 
     exit(EXIT_FAILURE); 
    } 
    printf("This prints now too\n"); 
    free(c); 

    // sort array of character pointers 

    // parse each environment variable and output 

    exit(0); 
} 

Для начала, я прочитал через пару десятков таНос & вопросов об ошибках сегментации на здесь и никто не кажется таким же, как у меня. Сказав это, если это дублирующий вопрос, вы бы указали мне на решение?

Привет всем, У меня возникла проблема с использованием malloc. Я скомпилировал и запускал свою программу один раз, и malloc работал. Затем я начал заполнять больше кода, чтобы решить проблему, и после этого первого запуска я получил ошибку сегментации. Ниже мой код в его последние рабочем состоянии (по-прежнему дает ошибку неисправности сегм хотя):

extern char **environ; 

int main(int argc, char *argv[]) { 
    // determine number of environment variables 
    int n = 0; 
    char *c = *environ; 
    while ((c = *environ++) != NULL) { 
     n++; 
     printf("%s\n", c); 
    } 
    printf("%s\n%d\n\n", c, n); 

    // allocate array to store character pointers to environment array 
    printf("This prints\n"); 
    if ((c = malloc((size_t) n)) == NULL) { 
     perror("Unable to allocate memory\n"); 
    } 
    printf("This does not print\n"); 
    free(c); 

    // sort array of character pointers 

    // parse each environment variable and output 

    exit(0); 
} 

Программа должна выделить память для массива полукокса, который будет использоваться для сортировки, анализировать и распечатывать имя-значение или пар имя-значение в зависимости от того, для чего установлено значение FORMAT. Первый цикл работает и выполняет итерацию через переменную окружения и выводит каждую пару имя-значение. В двух заявлениях printf я включил состояние, которое я вижу в терминале. У кого-нибудь есть идеи, что я делаю неправильно?

Кроме того, я попытался использовать следующий таНос строку:

char *new_c = malloc((size_t) n); 
char *new_c = malloc(n); 
char *new_c = malloc(1); 
char *new_c = malloc(sizeof(n)); 
int *ptr = malloc((size_t) n); 

Есть, вероятно, несколько других я пытался, но я все еще сбит с толком. Есть так мало строк кода, что я не уверен, как я мог бы возиться с этим на ранней стадии. Кроме того, для смеха, вот что я получаю, когда я использую бесплатно в терминале (с указанием меня память):

   total  used  free  shared buff/cache available 
Mem:  3036836  1404340  902852  104712  729644  1491248 
Swap:    0   0   0 

Я также попытался вызовом таНоса вне если заявление, как например:

c = malloc((size_t) n); 
if (c == NULL) { 
    perror("Unable to allocate memory\n"); 
} 

ответ

3

Здесь вы изменяете глобальную environ:

while ((c = *environ++) != NULL) { 

После цикла в то время, environ указывает на неинициализированного памяти.

malloc() ищет некоторые переменные среды, которые могут изменять его поведение и теперь разыменовывают указатель на неинициализированную память. Используйте:

int i = 0; 
while ((c = environ[i++]) != NULL) { 

Это должно исправить ошибку сегментации.

+0

Хорошо, позвоните, это была проблема, над которой я работал дальше. Теперь я не получаю ошибку сегментации, но этот оператор не распечатывает: printf («Это не печатает \ n»); – ZSButcher

+0

@ZSButcher Ну, это должно быть, я не вижу причины, почему нет. Можете ли вы показать полный модифицированный код? – Ctx

+0

Я изменяю условия оператора if на! = По ошибке. Кажется, все работает сейчас. Спасибо за хороший глаз! – ZSButcher

1

Две вещи с этим:

if ((c = malloc((size_t) n)) == NULL) { 
    perror("Unable to allocate memory\n"); 
} 

Вы выделяющие n байт, здесь. Это звучит, как вы хотите, чтобы выделить место для n указателей на char, так что вы должны заменить:

malloc(n * sizeof(char *)) 

Если это действительно то, что вы пытаетесь сделать, то c должен быть char **, не char *, и лучше еще бы:

c = malloc(n * sizeof *c) 

Кстати, вы, кажется, использует c для двух совершенно разных вещей. Как правило, лучше не делать этого с переменными - поскольку это затрудняет понимание вашей программы - и вместо этого использовать одну переменную для циклического перехода для печати переменных среды и другую для хранения динамически распределенного массива.

Также вы вызываете perror(), если malloc() не работает, но затем вы просто продолжаете прямо с вашей программой, как если бы не было ошибок. Фактически вы должны реагировать на провал такого характера, если ничего другого, вызвав exit(EXIT_FAILURE) после сообщения об этом.

+0

Выделение 'n * sizeof (char *)' в 'char *'. Возможно, я ошибаюсь, но я сомневаюсь в том, что OP это хочет. – ameyCU

+0

Я только что заменил свой malloc вашим, и я все еще получаю ошибку сегментации. Я также поставил звонок выхода, спасибо, что поймал это. – ZSButcher

+0

@ameyCU: Хорошая точка, обновленный ответ. –