В вашей схеме размещения нет ничего плохого, но есть ряд улучшений, которые можно сделать. Если ваш отладчик сообщает, что доступна строка из 30 элементов - что-то не так в том, как вы смотрите на информацию.
Во-первых, нет необходимости разыгрывать возврат malloc
, это не нужно. Смотрите: Я разыгрываю результат malloc? .
Избегайте exit
в функциях распределения. Вызывающая сторона должна иметь возможность корректно обрабатывать неудачу при выделении, а не выходить из программы в этот момент. Хотя exit
является действительным, оно серьезно ограничивает ваши варианты обработки ошибки. Вместо этого верните действительный указатель на успех, или NULL
в противном случае, и позвольте вызывающей стороне обработать ошибку. В случае неудачного размещения, вы можете free()
все предыдущие распределения перед возвратом NULL
.
Попробуйте использовать calloc
для выделения хранилища для matrix[row]
. calloc
устанавливает все байты, присвоенные нулю, эффективно инициализируя каждый элемент для каждой строки равным 0
, предотвращая неопределенное поведение при непреднамеренном доступе неинициализированного элемента после возврата.
Собрав все части вместе, вы можете сделать что-то похожее на:
/* allocatematrix allocates storage for a width x height matrix of type int.
* all elements are initialized zero. on success returns a pointer to pointer
* to type, otherwise all allocations are freed and NULL is returned.
*/
int **allocatematrix (int width, int height)
{
int **matrix;
int row; /* declare row in for loop declaration, unless c89 support needed */
matrix = malloc (height * sizeof *matrix); /* allocate pointers */
if (!matrix) { /* validate */
perror ("malloc-matrix"); /* malloc failure set errno, use it */
return NULL; /* evaluate return in caller */
}
for (row = 0; row < height; row++) { /* for each pointer */
matrix[row] = calloc (width, sizeof *matrix[row]); /* alloc rows */
if (!Matrix[row]) { /* validate */
perror ("calloc-matrix[row]"); /* ditto for calloc */
while (row--) /* loop over previous rows */
free (matrix[row]); /* free previously allocated rows */
free (matrix); /* free pointers */
return NULL; /* evaluate return in caller */
}
}
return matrix; /* return initial pointer address */
}
( примечание: , хотя и не является ошибкой, C обычно избегает использования camelCase
или MixedCase
имен переменных и функций в пользу всех строчных букв при резервировании заглавные имена для использования с макросами и константами. Это вопрос стиля - так что это полностью ваше дело)
( также обратите внимание: использование perror
вместо printf
для сообщения об ошибках. Когда функция устанавливает errno
при сбое, следует использовать perror
. Далее она уже обеспечивает вывод на stderr
. Если при сбое, когда errno
не установлено, используйте fprintf
(если требуется преобразование) или fputs
в противном случае и сообщите об ошибке на stderr
вместо stdout
)
Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.