Выделение (и освобождение) памяти для char * [64] в C - PullRequest
0 голосов
/ 08 июня 2010

Мне было интересно, как я мог бы выделить (и де-выделить) массив указателей на символы (char * [64]) в C. Я искал в Интернете примеры, но все они сосредоточены на других типах данных или одном размерные массивы.

Ответы [ 6 ]

1 голос
/ 08 июня 2010

Ответ на этот вопрос FAQ C .

Вот код, адаптированный для char * вместо int * с некоторыми примерами данных.

#include <stdlib.h>

#define nrows 10
#define ncolumns 64

int main(int argc, char* argv[])
{

    int i;

     //allocate 10 char*
    char **array1 = (char**)calloc(nrows,sizeof(char*));
    for(i = 0; i < nrows; i++)      
    {
        //allocate 64 chars in each row
        array1[i] = (char*)calloc(ncolumns,sizeof(char));  
        sprintf_s(array1[i],numcolumns,"foo%d",i);
    }

    for(i=0;i<nrows;i++)
        printf("%s\n",array1[i]);

     //prints:
     //  foo0
     //  foo1
     //  ..
     //  foo9
     for(i=0;i<nrows;i++)
           free(array1[i]);

     free(array1);

    return 0;
}
1 голос
/ 08 июня 2010

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

char **array;   
array = malloc(64 * sizeof(char *));

Когда придет время освободить его, вы просто сделаете как обычно:

free(array);

Обратите внимание, однако, что если указатели в массиве указывают на на что-либо (особенно на динамически выделяемую память), вам нужно отдельно работать с освобождением этой памяти - обычно до освобождает массив указателей.

0 голосов
/ 08 июня 2010

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

Предположим, что cItems - это целое число, представляющее собой число элементов в вашем массиве, скажем, 64. Предположим, aItemSizes [] содержит длины данных char для каждого элемента в вашем массиве:

int iItem;
char **aItems, *pData; 

for (cbCharData=iItem=0; iItem<cItems ; iItem++)  
  cbCharData += aItemSizes[iItem];
aItems = (char**)malloc(sizeof(char*)*cItems + cbCharData); 
for (iItem=0, pData=&aItems[cItems] ; iItem<cItems ; pData+=aItemSizes[iItem], iItem++)  
  aItem[iItem] = pData;

Теперь aItem [iItem] указывает на область памяти, которая может обрабатывать до символов aItemSizes [iItem], и вам нужно только одно выделение, которое на WAAAAAAAAAAAAAAAAAAAAAAAAAAY быстрее. Я прошу прощения за ошибки компиляции, потому что я не проверял это. Чтобы освободить его, вам нужны только бесплатные элементы.

0 голосов
/ 08 июня 2010

С риском быть очевидным (и менее общим, чем другие ответы), sizeof ( char * [64] ) равняется 64 * sizeof ( char * ), поэтому вы можете просто написать p = malloc ( sizeof ( char * [64] ) ) для выделения памяти и free ( p ) для ее освобождения.

0 голосов
/ 08 июня 2010

Если у вас есть тип, указанный в вашем вопросе:

char *foo[64];

Тогда вам не нужно явно выделять память для foo - это обычный массив. Чтобы выделить память для указателей в foo, просто используйте цикл:

int i;

for (i = 0; i < 64; i++)
{
    foo[i] = malloc(somesize);
}

(Однако вам не следует использовать магическое значение 64 в цикле; либо используйте #define FOOSIZE 64, либо используйте sizeof foo / sizeof foo[0] для определения размера массива).

0 голосов
/ 08 июня 2010

Вы выделяете память в куче с помощью malloc:

char** pPointers;
pPointers = malloc(sizeof(char*) * 64);

Теперь у вас есть массив из 64 указателей на символы.

Вы освобождаете память этим вызовом:

free(pPointers);

Возможно, вы присвоите значения вашему массиву:

pPointers[0] = "abc";
pPointers[1] = &cSampleCharVariable;
pPointers[2] = strdup("123");

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

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