2017-02-06 4 views
-1

Если у меня есть целочисленный массив:Почему один способ malloc seg fault, а другой нет?

int *array; 

array = malloc(5 * sizeof(int)); 

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

Но если я создаю что ИНТ указатель и передать ему функции и таНос внутри функции, я не могу получить доступ к/заданные значения в массив , если я не передать его в массив как указатель к указателю?

some_void_function(int *array) { 
    array = malloc(5 * sizeof(int)) 
} 

int *array; 
some_void_function(array); 

*(array + 3) = 5; // DOES NOT WORK 

Чтобы это исправить, я могу сделать массив принять (интермедиат ** массив) в качестве параметра и передать в адрес указателя (так указатель на указатель), разыменования и назначьте его таНос :

some_void_function(int **array) { 
    *array = malloc(5 * sizeof(int)) 
} 

int *array; 
some_void_function(&array); 

*(array + 3) = 5; // WORKS 

Может кто-нибудь объяснить это мне? Разве я не делаю то же самое в обеих ситуациях? Передайте адрес, а затем просто разыменовываете это то же самое, что и просто в одном указателе в первую очередь?

+0

Как это может быть одно и то же, если это не так? Вызов 'some_void_function (array);' вы не изменяете 'array', поскольку он передается по значению. –

ответ

2

Указатели - это переменные, которые содержат адреса. Но они подчиняются тем же правилам, что и все другие типы переменных, то есть они передаются по значению.

void some_void_function(int *array) { 
    array = malloc(5 * sizeof(int)) 
} 

array является локальным для some_void_function, и любые изменения, внесенные в его стоимости не отражается в указателе он был скопирован.

Чтобы изменить переменные (указатели включены) в вызывающем коде, у вас есть два варианта:

  1. Pass по указателю, что означает указатель на указатель:

    void some_void_function(int **array) { 
        *array = malloc(5 * sizeof(int)) 
    } 
    
  2. Верните адрес, который вы выделили, и присвоить его указателю:

    int* some_allocating_function() { 
        return malloc(5 * sizeof(int)) 
    } 
    //... 
    int *array = some_allocating_function(); 
    
+0

Чтобы быть понятным, создается локальная копия * указателя *? Поэтому, когда я делаю malloc внутри функции, я на самом деле просто malloc'ing к другому указателю (локальному), а не к тому, к которому я ожидаю malloc? – Zhinkk

+0

@Zhinkk - Right in one :) – StoryTeller

+0

Извините, это создает еще одну путаницу для меня: если указатель передается по значению, почему это работает? недействительного тест (INT * массив) { * (массив) = 10 } и в основном, массив изменяется. Но разве вы не сказали, что указатель передается по значению? – Zhinkk

2

Thats becuase с проходит paramters по значению

some_void_function(int *array) { 
    array = malloc(5 * sizeof(int)) 
} 

этот код только изменяет локальную копию array, он не изменится, что звонящие копия array

этот код

some_void_function(int **array) { 
    *array = malloc(5 * sizeof(int)) 
} 

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