Итак, я некоторое время боролся с этим, и после долгих ночных выдергиваний волос я решил посмотреть, не хотите ли вы все попробовать.
В итоге Я пытаюсь настроить динамически распределяемую структуру для использования в программе, передавая код выделения другой функции за пределами main. Я знаю два способа сделать это: во-первых, заставить функцию возвращать указатель на выделенную структуру, например:
typeStruct *someFunction()
Или два, передать двойной указатель на структуру, разыменовать ее и выделить память на внутренний указатель. Например:
void someFunction(typeStruct **ptr)
Я пытаюсь сделать последнее, так как хочу использовать возвращаемое значение для флага char, а не самой структуры.
К сожалению, похоже, что изменения сделаны по указанию указателя не выходите за рамки функции. Мне удалось воспроизвести мою проблему с помощью более простого примера программы. Вот код:
test. c:
#include "testheader.h"
int main() {
char success = 0;
test *t;
printf("\nBefore setup (in Main), Test: %d", t);
success = setupTest(&t);
printf("\nAfter setup (in Main), Test: %d", t);
free(t->numbers);
free(t);
return success;
}
testheader. c:
#include "testheader.h"
const int NUM_NUMBERS = 100;
char setupTest(test **ptr) {
printf("\nBefore deference, Test: %d", *ptr);
char flag = 0;
test *t = *ptr;
printf("\nBefore malloc, Test: %d", t);
t = malloc(sizeof(test));
printf("\nAfter malloc, Test: %d", t);
if(t != NULL) {
t->numbers = malloc(sizeof(int) * NUM_NUMBERS);
if(t->numbers != NULL) {
for(int i = 0; i < NUM_NUMBERS; ++i) t->numbers[i] = i;
} else flag = 1;
} else flag = 1;
printf("\nEnd of setup, Test: %d", t);
return flag;
}
testheader.h:
#ifndef TESTHEADER_H
#define TESTHEADER_H
#include <stdlib.h>
#include <stdio.h>
typedef struct test_t {
int *numbers;
} test;
char setupTest(test **);
#endif
Вот как я его компилирую: g cc test. c testheader. c -o test.exe
Я использую g cc 5.1.0 для компиляции в git bash и консоль Windows 10 для запуска.
Вот мой вывод при запуске test.exe: Отладка консоли
И затем происходит сбой. Как можно видеть, внутренняя функция ведет себя так, как и ожидалось, хотя код за ее пределами не отражает распределение внутри, как если бы я только что передал сам указатель, а не передавал по ссылке с двойным указателем.
Есть ли что-то, чего мне здесь не хватает?
Диагноз:
Строки
test *t = *ptr;
t = malloc(sizeof(test));
Влияет только на локальную переменную t, а не на содержимое ** ptr.
Решение:
mallo c на содержимое ** ptr, а не на локальную переменную, чтобы при возврате выделение не выходило за пределы go , И поменяйте местами две строки.
*ptr = malloc(sizeof(test));
test *t = *ptr;