Хорошо, хотя я не совсем понимаю, что вы пытаетесь выполнить с помощью функции messageVector
, я думаю, что ваш вопрос является законным, поэтому я постараюсь дать вам некоторое представление.
Прежде всего, есть еще одна проблема с кодом, который вы представили в функции main
. Если malloc
сбой при назначении строк maxColumns2
, вы выходите без free
любых ранее выделенных строк.
Обратите внимание, что я намеренно поменял текст maxColumns2
и maxRows
, потому что в общем контексте он имеет немного больше смысла. По идее, вы начинаете с выделения строк указателей int
, а затем для каждой строки вы выделяете столбцы int
.
Таким образом, вы можете попробовать что-то вроде этого вместо того, чтобы ...
/* Allocating Memory for the double pointer. */
columnVect = malloc(maxRows * sizeof(int *));
if (columnVect == NULL){
fputs("Memory error.\n", stderr);
exit(0);
}
for (int i=0; i < maxRows; i++)
{
columnVect[i] = malloc(maxColumns2 * sizeof(int));
if (columnVect[i] == NULL)
{
fputs("Memory error.\n", stderr);
for (int j = i-1; j > -1; j--)
free(columnVect[j]);
free(columnVect);
columnVect = NULL;
exit(0);
}
}
Внутреннего цикла (с помощью j
счетчика) идет от последней успешно выделенной строки к 1-ому, free
ИНГАМ их на путь. После этого columnsVect
также получает free
'ed (то есть память зарезервирована для указателей int
перед внешним контуром), и она установлена в NULL
.
Возможно, я, вероятно, задираю здесь, поскольку большинство современных операционных систем освободят любую память, выделенную вашей программой после ее завершения, но это хорошая привычка всегда освобождать выделенную память. С одной стороны, это помогает при отладке вашего кода. Он также защищает вас от создания утечек памяти в будущем, если вам нужно внедрить свой текущий код в более крупный проект (например, в библиотеку).
Теперь, передавая ссылку двойного указателя на функцию, хороший и простой пример imho будет функцией, которая освобождает память, зарезервированную для этого указателя, и устанавливает указатель на NULL
. Что-то вдоль этих линий:
void free_int2d(int ***int2d, int nrows)
{
int i;
if (nrows < 1) {
printf("*** warning: %s() failed, no memory freed\n", __func__);
return;
}
if (!int2d || !*int2d)
return;
for (i=0; i < nrows; i++) {
if ((*int2d)[i])
free((*int2d)[i]);
}
*int2d = NULL;
}
Надеюсь, это говорит само за себя, но только в том случае, позвольте мне отметить несколько вещей.
Главное, чтобы написать *int2d
всякий раз, когда вы хотите выразить свой оригинальный двойной указатель внутри функции (то есть строки указателей int
).
Другой - то, что, если вы хотите выразить i
'th ряд, вы пишете (*int2d)[i]
. Вы должны явно заключить 1-е разыменование в круглых скобках ... 2-я разыменованная операция выполняется неявно через нотацию [].
Наконец, в качестве примера передачи по ссылке двойной указатель на эту функцию, здесь внутренний цикл исходного кода, переписанного с помощью этой функции free_int2
...
for (int i=0; i < maxRows; i++)
{
columnVect[i] = malloc(maxColumns2 * sizeof(int));
if (columnVect[i] == NULL)
{
fputs("Memory error.\n", stderr);
free_int2d(&columnVect, i);
exit(0);
}
}
Это существенно упрощается, таким образом, более читаемым. free_2d(&columnVect, maxRows)
также должен быть вызван по успешному завершению программы (по причинам, описанным выше).
EDIT
Из соображений производительности, вы можете рассмотреть вопрос предварительного выделения буфера для malloc
ИНГ столбцов, и перераспределить его по мере необходимости (возможно, путем удвоения его размера). Но это дает немного более сложный код.
Что такое функция 'messageVector', вы хотите изменить двойной указатель, выделенный ранее? Если нет, вам не нужно выделять его. – Rohan
Да, возможно, кто-нибудь может сказать вам решение, если код был читабельным и достаточно маленьким. –
Цель состоит в том, чтобы умножить возвращаемое значение. – unixeO