выделение памяти для n указателей нового определенного типа данных - PullRequest
1 голос
/ 27 мая 2020

Мне нужно:

a) определить тип данных (по моему собственному выбору) с именем mytype .

b) и иметь функцию getmemory (int n ), зарезервировать память для n значений типа mytype и вернуть указатель. Я реализовал это, как показано ниже:

typedef int mytype;
// b) 
mytype *getmemory(int n)
{
    mytype *p;
    //allocate space for n values of mytype.
    p = (mytype *)malloc(n * sizeof(mytype));
    return p;
}

Теперь я хочу изменить код, чтобы зарезервировать и вернуть память для n указателей на mytype . Я не уверен, как это сделать, я много искал в inte rnet (также в StackOverflow), но я все еще не уверен, как лучше всего решить задачу. Ниже у меня есть два возможных решения, и я хотел бы знать, какое из них правильное.

Решения:

1. Решение:

mytype **getmemoryForNPointer(int n_pointers, int n_mytype)
{
    mytype **p = NULL;
    p = (mytype **) malloc(n_pointers  * sizeof(mytype *));

    return p;
}

2. Решение

mytype **getmemoryForNPointer(int n_mytype, int n_pointers)
{
    mytype **p = NULL; 

    //allocate n pointers to mytype first:
    p = (mytype **) malloc(n_pointers * sizeof(mytype*));
    //I'm not sure the for loop belongs in there.   
    for (int i = 0; i < n_pointers; i++)
    {
        // For each such pointer, allocate space for n mytype-values.
        p[i] = (mytype *)malloc(n_mytype * sizeof(mytype));
    }
    return p;
}

- следующий код эквивалентен второму коду?

mytype **getmemoryForNPointer(int n_mytype, int n_pointers)
{
    mytype *p[n_pointers];
    for (int i = 0; i < n_pointers; i++)
    {
        p[i] = (mytype *)malloc(n_mytype* sizeof(mytype));
    }

    return p;
}

1 Ответ

3 голосов
/ 27 мая 2020

Оба ваших «решения» в какой-то мере верны (но см. Здесь: Приведу ли я результат mallo c? ).

Разница в том, что первое выделяет массив указателей, но затем ничего не делает с этими указателями (т.е. все они будут содержать неопределенные и непригодные для использования адреса). Вы можете улучшить эту версию, используя calloc вместо malloc, который инициализирует все эти указатели на NULL (так что каждый может быть затем протестирован в другом месте вашего кода, прежде чем пытаться разыменовать его).

Второе решение также выделяет память для каждого блока данных и назначает адреса этих блоков указателям. В этом смысле второй является более полным , но не обязательно более правильным .

Но не забудьте освободить данные, когда закончите:

void freememoryForNPointer(mytype** ptr, int n_pointers)
{
    for (int i = 0; i < n_pointers; i++) free(ptr[i]);
    free(ptr);
}
...