Создание указателя на указатель с помощью malloc - PullRequest
1 голос
/ 06 октября 2009

код

char** p = (char **) malloc(sizeof(char **) * size); //Where size is some valid value.
p[1] = (char*) malloc(sizeof(char) * 30);

Хорошо ли с кодом выше?

Мое понимание

p -> +---------+
     0 char*   + -> {c,o,d,e,\0}
     +---------+

     +---------+
     1 char*   + -> {t,o,a,d,\0} //The assignment of these values is not shown in the code.
     +---------+

Так что вместо этого мы должны написать

char** p = (char **) malloc(sizeof(char *) * size);

Я прав?

А p [0] означает * (p + 1), где p + 1 будет указывать на «жабу», так что «жаба» будет возвращена?

Ответы [ 7 ]

8 голосов
/ 06 октября 2009

Как правило, '* -ness' вещи, которую вы берете в размер вызова malloc, должна быть на 1 '*' меньше, чем указатель, получающий память malloc.

например:

char * p = malloc(sizeof(char) * somesize);

и

char ** p = malloc(sizeof(char *) * somesize);
2 голосов
/ 06 октября 2009

Да и нет. Вы правы, что при первом выделении должно использоваться sizeof( char * ), но поскольку указатели и указатели на указатели имеют одинаковый размер, это не имеет значения.

Но p[0] указывает на буфер, содержащий "код", в то время как p[1] указывает на буфер, содержащий "жабу". Код выделяет массив указателей, а затем заполняет второй элемент массива, оставляя первый неинициализированным.

2 голосов
/ 06 октября 2009

Да, вы в основном размещаете здесь массив char * размером size. sizeof(char *) действительно следует использовать вместо sizeof(char **), но на практике это ничего не изменит, поскольку указатель всегда имеет одинаковый размер.

p [0] означает * p, я полагаю, вы имели в виду p [1] означает * (p + 1), что правильно.

2 голосов
/ 06 октября 2009

Да, вам следует malloc() sizeof(char*), поскольку вы намереваетесь сохранить char* в массиве.

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

p[0] означает *(p + 0), а не (*p + 1). p[1] будет означать *(p + 1).

1 голос
/ 06 октября 2009

Я всегда так делаю:

#include <stdlib.h>
pointer = malloc(ELEMENTS * sizeof *pointer);
/* check if pointer is NULL */

В вашем случае это становится:

#include <stdlib.h>
char** p = malloc(sizeof *p * size); //Where size is some valid value.
/* check if p is NULL */
p[1] = malloc(sizeof *(p[1]) * 30);
/* check if p[1] is NULL */

Примечание: В C возвращаемое значение malloc не должно быть приведено! void * вполне допустимо для присвоения любому другому типу указателя. В C ++ это может быть иначе.

1 голос
/ 06 октября 2009

Да, вы должны написать

char** p = (char **) malloc(sizeof(char *) * size);

Но нет, p[0] означает *(p + 0), где p+0 будет указывать на "code", поэтому будет возвращено "code".

Если вы хотите "жабу", используйте p[1], что означает *(p + 1).

1 голос
/ 06 октября 2009

Ты прав. Должно быть

char** p = (char**) malloc(sizeof(char*) * size);

Что касается вашего последнего вопроса, я не совсем понимаю. p [0] означает * (p + 0). p [1] означает * (p + 1).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...