2015-06-26 2 views
1

У меня есть функция f1, которая ожидает указатель на пустоту. От вызывающего я хочу иметь общую логику передачи указателя void на A, который внутренне изменяет указатель.void pointer как аргумент в функции

образец кода наклеивается ниже:

#include "stdio.h" 
#include "malloc.h" 
void f1(void* a) 
{ 
    printf("f(a) address = %p \n",a); 
    a = (void*)(int*)malloc(sizeof(int)); 

    printf("a address = %p \n",a); 
    *(int*)a = 3; 

    printf("data = %d\n",*(int*)a); 
} 

void f(void) 
{ 
    void* a1=NULL; 
    printf("a1 address = %p \n",a1); 

    f1(a1); 

    printf("a1 address = %p \n",a1); 
    printf("Data.a1 = %d\n",*(int*)a1); 
} 

int main() 
{ 
    f(); 
} 

Но это вызывает ошибку сегментации. Есть ли способ заставить его работать без изменения прототипа функции f1?

+1

Я видел людей, литых 'void *' на что-нибудь вроде 'int *' или 'float *' для возвращаемого значения 'malloc()', но вы ... 'void *' -> 'int *' - > 'void *'? Зачем? –

+0

'malloc.h' ....? – alk

+2

whhyyyyyyyy это так много? Это просто еще один вопрос «Я не стал искать, что означает« пропуск по значению »... –

ответ

5

C использует pass-by-value для передачи аргументов функции. Если вам нужно изменить переданную переменную изнутри функции, вам нужно иметь указатель на переменную.

В вашем случае это должен быть указатель на указатель.

В противном случае, после вызова f1(a1);, в f(), a еще NULL и разыменования он вызывает undefined behaviour. Ошибка сегментации является одним из побочных эффектов UB.

Это говорит,

  1. Пожалуйста see why not to cast возвращаемое значение malloc() и семьи в C.

  2. #include "malloc.h"malloc(), скорее всего используйте #include <stdlib.h>. Он объявлен в файле заголовка stdlib.h.

1

Необходимо изменить указатель, а не на данные. Таким образом, вы должны передать указатель на указатель, как этого

void f1(void **a) 
{ 
    int *b; 
    b = malloc(sizeof(*b)); 

    printf("b address = %p \n", b); 
    if (b != NULL) 
    { 
     b[0] = 3; 
     printf("data = %d\n", *(int *) b); 
    } 
    *a = b; 
} 

, как вы делаете это, указатель внутри f1 является копией переданного указателя, они оба содержат одинаковое начальное значение NULL, значение использованного в f() для инициализации a1, но вы изменяете значение только локального указателя.

Вы затем разыскиваете a1, который по-прежнему NULL, и разыменовывая указатель NULL, вызывает неопределенное поведение. В вашем случае поведение заключается в том, что происходит ошибка сегментации.

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