Передача указателей на другую функцию, создающая ошибку сегментации - PullRequest
0 голосов
/ 15 ноября 2018
 struct temp {
     int a;
 };
 int pass(struct temp **); //passing var
 int pass(struct temp ** var1) { //passing var
     (* var1)->a = 100;
     return 0;
 };
 int main() {
     struct temp * var2 = NULL;
     var2->a = 10;
     printf("\nbefore pass var2->a = %d", var2->a);
     pass(&var2);
     printf("\nafter pass var2->a = %d", var2->a); 
     return 0;
 }

bash $! Gc gcc sample2.c; ./a.exe Ошибка сегментации (ядро сброшено)

Я пытаюсь обновить значение a внутри функции pass (), но получаю ошибку seg. Не уверен, что происходит не так. Ищете исправленный код! ТИА!

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Здесь

 struct temp * var2 = NULL;

вы создаете указатель на struct temp и инициализируете его в NULL.Это только указатель - есть не какой-либо памяти для struct temp.

Затем вы делаете:

var2->a = 10;

, что означаетВы разыменовываете нулевой указатель.Это не удастся.

Попробуйте:

struct temp * var2 = malloc(sizeof *var2);  // Create pointer and allocate 
                                            // memory for a struct temp

.

Кстати: вам не нужно передавать двойной указатель на функцию.Просто int pass(struct temp *); сделает.

Таким образом, полный код может быть:

#include <stdio.h>
#include <stdlib.h>

 struct temp {
     int a;
 };

 int pass(struct temp *); //passing var
 int pass(struct temp * var1) { //passing var
     var1->a = 100;
     return 0;
 };

 int main() {
     struct temp * var2 = malloc(sizeof *var2);
     var2->a = 10;
     printf("\nbefore pass var2->a = %d", var2->a);
     pass(var2);
     printf("\nafter pass var2->a = %d", var2->a); 
     free(var2);
     return 0;
 }

Передача двойного указателя в коде, как это необходимо, только если вы хотите изменить значение var2 в основном.Например, если функция должна выделять больше памяти (т. Е. Больше struct temp элементов).

Это может выглядеть следующим образом:

#include <stdio.h>
#include <stdlib.h>

 struct temp {
     int a;
 };

 int pass(struct temp **);
 int pass(struct temp ** var1) {
     free(*var1);                         // Free previous allocation
     *var1 = malloc(20 * sizeof **var1);  // Allocate 20 struct temp
     (*var1)[0].a = 100;
     (*var1)[1].a = 200;
     return 0;
 };

 int main() {
     struct temp * var2 = malloc(sizeof *var2);  // Allocate 1 struct temp
     var2->a = 10;
     printf("\npointer before pass var2 = %p", (void*)var2);
     printf("\nbefore pass var2[0].a = %d", var2[0].a);
     // printf("\nbefore pass var2[1].a = %d", var2[1].a);  // ILLEGAL HERE

     pass(&var2);

     printf("\npointer after pass var2 = %p", (void*)var2);
     printf("\nafter pass var2[0].a = %d", var2[0].a); 
     printf("\nafter pass var2[1].a = %d", var2[1].a);   // LEGAL HERE

     free(var2);
     return 0;
 }

Возможный вывод:

pointer before pass var2 = 0x563d28afa010
before pass var2[0].a = 10
pointer after pass var2 = 0x563d28afb040
after pass var2[0].a = 100
after pass var2[1].a = 200

Обратите внимание, как изменилось значение указателя.

0 голосов
/ 15 ноября 2018

В основном вы делаете var = NULL;, а в следующей строке вы делаете var2->a = 10;, что означает, что вы пытаетесь присвоить значение структуре, на которую указывает var, но var пока не указывает ни на одну структуру.

Возможно, что вы хотите сделать, это:

 struct temp {
     int a;
 };
 int pass(struct temp *); //passing var
 int pass(struct temp * var1) { //passing var
     var1->a = 100;
     return 0;
 };
 int main() {
     struct temp var2;
     var2.a = 10;
     printf("\nbefore pass var2->a = %d", var2.a);
     pass(&var2);
     printf("\nafter pass var2->a = %d", var2.a); 
     return 0;
 }
...