Присвоение памяти для удвоения указателя?

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

    char **ptr;
    fp = fopen("file.txt","r");
    ptr = (char**)malloc(sizeof(char*)*50);
    for(int i=0; i<20; i++)
    {
       ptr[i] = (char*)malloc(sizeof(char)*50);
       fgets(ptr[i],50,fp);
    }

вместо этого я просто присваиваю большой блок памяти и храню строку

  char **ptr;
  ptr = (char**)malloc(sizeof(char)*50*50);

это было бы неправильно? И раз так почему это?

15
задан umeshksingla 19 August 2017 в 22:22
поделиться

3 ответа

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

char *x;  // Memory locations pointed to by x contain 'char'
char **y; // Memory locations pointed to by y contain 'char*'

x = (char*)malloc(sizeof(char) * 100);   // 100 'char'
y = (char**)malloc(sizeof(char*) * 100); // 100 'char*'

// below is incorrect:
y = (char**)malloc(sizeof(char) * 50 * 50);
// 2500 'char' not 50 'char*' pointing to 50 'char'

Из-за этого вашим первым циклом будет то, как вы делаете в C массив символьных массивов / указателей. Использование фиксированного блока памяти для массива символьных массивов - это нормально, но вы должны использовать один char * , а не char ** , поскольку у вас не будет никаких указателей в память, просто char с.

char *x = calloc(50 * 50, sizeof(char));

for (ii = 0; ii < 50; ++ii) {
    // Note that each string is just an OFFSET into the memory block
    // You must be sensitive to this when using these 'strings'
    char *str = &x[ii * 50];
}
14
ответ дан 1 December 2019 в 04:34
поделиться

Двойной указатель - это просто указатель на другой указатель. Таким образом, вы можете выделить его следующим образом:

char *realptr=(char*)malloc(1234);
char **ptr=&realptr;

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

1
ответ дан 1 December 2019 в 04:34
поделиться

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

Например, если вы хотите создать массив строк, вы можете просто сделать:

char** stringArray = calloc(10, 40);

это создаст массив размером 10, каждый элемент будет строкой длиной 40.

таким образом вы можете получить доступ к этому с помощью stringArray [5] и получим строку в 6-й позиции.

это одно использование, другие, как упомянуто выше, являются указателем на указатель и могут быть выделены просто:

char* str = (char*)malloc(40);
char** pointerToPointer = &str //Get the address of the str pointer, valid only in the current closure.

подробнее здесь: хорошее руководство по массивам

-5
ответ дан 1 December 2019 в 04:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: