Извините, все, что мы вам предложили сделать, чтобы исправить это, объединило и сломало снова!Исходя из исходного кода, вот необходимые вам корректировки:
- Подпись функции должна быть
char ***result
вместо char **result
. - Распределение массива должно быть
*result = malloc(...)
вместо result = malloc(...)
. - Указатель компонента никогда не сохранялся в массиве результатов, после строки
component[componentLength] = '\0';
следует поставить строку (*result)[numberOfComponents] = component;
(скобка необходима, поскольку параметр результата былизменено на char***
). - И, наконец, вызов функции должен выглядеть примерно так:
strspl(..., &result);
вместо strspl(..., result);
Указатели всегда были одной из самых сложных вещей для понимания при работе в C / C ++ ... Позвольте мне посмотреть, могу ли я объяснить это:
Допустим, у нас есть вызывающая сторона со стеком, подобным этому:
Address - Data - Description
0x99887760 - 0xbaadbeef - caller-result variable (uninitialized garbage)
Когда вызов выполняется следующим образом: strspl(..., result);
, компилятор копирует локальный указатель (0xbaadbeef
) в стек strspl
:
Address - Data - Description
0x99887750 - 0xbaadbeef - strspl-result variable (copy of uninitialized garbage)
...
0x99887760 - 0xbaadbeef - caller-result variable (uninitialized garbage)
Теперь, когда мы вызываем result = malloc(...)
и копируем результат в локальную переменную strspl-result, мы получаем:
Address - Data - Description
0x99887750 - 0x01000100 - strspl-result variable (new array)
...
0x99887760 - 0xbaadbeef - caller-result variable (uninitialized garbage)
Очевидно, что не обновляется переменная результата вызывающей стороны.
Если вместо этого мы вызываем адрес переменной результата: strspl(..., &result);
, мы получаем это:
Address - Data - Description
0x99887750 - 0x99887760 - strspl-result variable (pointer to the caller's result)
...
0x99887760 - 0xbaadbeef - caller-result variable (uninitialized garbage)
И затем, когда мы вызываем result = malloc(...)
, мы получаем это:
Address - Data - Description
0x99887750 - 0x01000100 - strspl-result variable (new array)
...
0x99887760 - 0xbaadbeef - caller-result variable (uninitialized garbage)
Все еще не совсем то, что мы хотим, потому что вызывающая сторона никогда не получает указатель на массив.
Если вместо этого мы вызываем *result = malloc(...)
, мы получаем это:
Address - Data - Description
0x99887750 - 0x99887760 - strspl-result variable (pointer to the caller's result)
...
0x99887760 - 0x01000100 - caller-result variable (new array)
Таким образом, когда мы возвращаемся, мы перезаписываем мусор вызывающей стороны нашим новым malloc
'd массивом.
Как видите, компилятор копирует адрес переменной вызывающего в стек вызываемой функции.Поскольку она скопирована, функция не может изменить ее, пока вызывающая сторона не передаст указатель на ее переменную (именно поэтому она должна быть char***
, а не char**
).
Я надеюсь, что все проясняется, не делая этотруднее понять!: -Р