2012-06-11 15 views
4

При определенном распределении памяти я нахожу это. Но я этого не понимаю.Что здесь означает «point»?

char * mem_alloc() 
{ 
    char *point; 
    char *a; 
    point = (char *)malloc(block_num); 

    a = *(char**) point; 
    return a; 
} 
+9

это означает неопределенное поведение :) – dasblinkenlight

+4

Эта функция полная не-смысл. Я бы убежал от того, что использует этот код. – Corbin

+1

Хорошо, что вы этого не понимаете .. Лучше уйти, чем понять .. – Krishnabhadra

ответ

8

char * mem_alloc()

По моему опыту, функции, возвращающие указатель почти всегда является признаком некорректной разработки программы. Такой указатель может указывать на следующее:

  • локальной переменной (вопиющей ошибкой, UB)
  • глобальный/статический (дизайн бедных программы, а также не поточно-)
  • динамической памяти (плохая программа дизайн, код, используя память должны обрабатывать распределение, большой потенциал для утечек)
  • или к одному из параметров, передаваемых в функцию (плохой дизайн программы, неясная функция интерфейс)

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

point = (char *)malloc(block_num);

Этот код означает, что тот, кто писал его путают над тем, как таНос работает и как пустота указателей работы.Результат malloc никогда не должен быть типичным, см. this и this. Призыв к typecast означает, что программист запутался в языке C и/или что они пытаются скомпилировать C-код на компиляторе C++.

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

a = *(char**) point;

Это означает, взять адрес точки, которая указывает на неинициализированного памяти в куче, то вид, что точка является указателем указатель на и таким образом обработать содержимое мусор куча, как если бы это был указатель. Затем верните этот указатель, указывая на случайное местоположение в ла-ла земли, на вызывающего. И при этом создайте утечку памяти.

+0

спасибо, он используется для создания списка ссылок. –

+0

ptr = (char *) malloc (block_num * size); (k = 0; k

+0

@ chenyoufu123 Этот код полностью отличается от того, что вы разместили, поэтому я не понимаю, как это будет актуально? – Lundin

0

Это, кажется, указывает значение точки (которое является адресом).
a = *(char**) point;
Вышеприведенный оператор указывает на точечную точку на - «указатель на указатель» в части «(char **) point». После этого у вас есть * для де-ссылки, которая меняет его на
значение (указатель на указатель)
=> указатель.
Таким образом, значение (скорее адрес), хранящееся в точке, копируется в a.
Я до сих пор не знаю, почему этот код написан.

+0

Я думаю, что понял. Я пишу его для повторного использования памяти –

0

Код, который вы опубликовали, является глупым - вы уверены, что он полон?

"point" и "a" - оба указателя.

«a» инициализируется «точкой» ... но «точка» полностью неинициализирована. Плохие вещи произойдут, если вызывающий пытается использовать возвращаемое значение «a».

Вот еще один пример:

struct Point { 
    int x; 
    int y; 
}; 

... 

char * mem_alloc (int size) 
{ 
    return (char *)malloc (size); 
} 

... 
    Point *my_point = (Point *)mem_alloc (sizeof (struct Point)); 
    ... 

Этот фрагмент также глупо ... но, надеюсь, это показывает немного того, что может быть обоснование кода вы смотрите ...

+0

er, да, я забыл malloc –

0

a содержит значение, сохраненное в местоположении, указанном point. Поскольку point неинициализирован, он указывает на случайное местоположение, которое содержит случайное значение, и, следовательно, теперь a указывает на случайное значение, которое должно было начаться.

Таким образом, код является не-оператором.

0

Если посмотреть на концепцию malloc, она всегда возвращает базовый адрес выделенной области памяти, фактический синтаксис функции malloc является Синтаксис:

pointer_to_store_base_add_of_mem = (data_type_of_allocated_memory)malloc(size_of_array) 

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

0

Глядя на код chenyoufu123 вывешенных в комментарии ответа Лундина в:

ptr = (char *)malloc(block_num * size); 
for(k=0; k<block_num-1; k++) { 
    *((char **)(ptr + k*size)) = ptr + (k+1) * size; 
} 
*((char **)(ptr + k*size)) = NULL; 

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

ситуация - при условии, что код «правильно» - что у вас есть

struct Node 
{ 
    struct Node *next; 
    /* More members */ 
}; 

и size_t size = sizeof(struct Node); (имена будут отличаться, наверное). Тогда

ptr = (char *)malloc(block_num * size); 

выделяет память для block_num смежных struct Node с. Можно было бы обычно выделяют, что в качестве

struct Node *ptr = malloc(block_num * sizeof *ptr); 

Петля

for(k=0; k<block_num-1; k++) { 
    *((char **)(ptr + k*size)) = ptr + (k+1) * size; 
} 
*((char **)(ptr + k*size)) = NULL; 

затем интерпретирует адрес k * sizeof(struct Node) позади начала блока памяти, ptr + k*size, как указатель на указатель (а char**, но на большинстве Архитектура ПК в настоящее время, это не важно, поскольку все указатели объектов имеют одно и то же представление - если это важно, код все равно нарушается) и записывает адрес следующего sizeof(struct Node) размера памяти в это место. Так как указатель next является первым членом struct Node, который записывает адрес следующего struct Node в список указателю next текущего тока struct Node. Наконец, указатель next последнего struct Node установлен в NULL.

Обычный способ написания этого

struct Node *ptr = malloc(block_num * sizeof *ptr); 
int k; 
for(k = 0; k < block_um - 1; ++k) 
{ 
    ptr[k].next = &ptr[k+1]; // or ptr + (k+1), if you prefer 
} 
ptr[block_num-1].next = NULL; 

не только понятнее, он также имеет преимущество работы на платформах, где char* и struct Node* имеют различные размеры или представления.

Смежные вопросы