2016-05-24 10 views
-1

Версия 1:Как использовать двойной указатель в качестве указательных массивов?

struct mydef_s1 { 
    int argc; 
    char *argv[3]; 
};   

struct mydef_s1 *p1 = (struct mydef_s1*) malloc (sizeof (struct mydef_s1));  
p1->argv[0] = malloc (8); 
p1->argv[1] = malloc (16); 
p1->argv[2] = malloc (24); 

Now, I want to achieve above with the following structure declaration? 

Версия 2:

struct mydef_s2 { 
    int argc; 
    char **argv; 
}; 

Если я прав, то следующий хотел бы выделить только 8 байт (4 для указателя памяти & 4 для целого числа в моем машина)

struct mydef_s2 *p2 = (struct mydef_s2*) malloc (sizeof (struct mydef_s2)); 

Что делает uld Я делаю, чтобы сделать следующее?

p2->argv[0]= malloc(4); 
p2->argv[1]=malloc(8); 
+0

Вы имели в виду 'p1-> argv [2] = malloc (24);'? –

+0

Похож на ужасную идею. Как вы даже знаете, сколько выделенного блока для каждой записи в массиве? Возможна проблема XY. Чего вы на самом деле хотите достичь? – Olaf

ответ

0

В случае указатель на указатель, как

struct mydef_s2 { 
    int argc; 
    char **argv; 
}; 

вы должны сначала выделить память для argv себя, то для argv[i] с.

Нечто подобное (код без проверки ошибок)

argv = malloc(n * sizeof*argv); //allocate memory to hold 'n' number of 'argv[i]'s 
    for (i = 0; i < n; i++) 
     argv[i] = malloc(32); //allocate individual `argv[i]`s 

будет делать эту работу.

+0

Получил это спасибо! – sniper

+0

@ sniper, если вы считаете, что это лучший ответ на ваш вопрос, пожалуйста, примите его, установив флажок рядом с ним. –

+0

@sniper: Обратите внимание, что это отличается от подхода в вашем вопросе, который использует блоки с переменным размером для каждого указателя. Если вам действительно нужен постоянный размер, используйте вместо него 2D-массив. Это может быть выделено/освобождено с помощью одного вызова. В противном случае вы должны отслеживать размеры каждого блока. «Строка» с элементом _flexible array_ будет полезна. – Olaf

0

Указатель в C ведет себя как массив. Указатель на указатель, однако, является чем-то совершенно отличным от двухмерного массива.

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

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

Другой вариант - имитировать то, что делает компилятор для двухмерных массивов. Выделите n * m chars как единый размерный массив и перейдите в него с помощью формулы i = r*m + c, где r - это индекс строки, m - это размер строки, а c - индекс столбца.

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

+0

Если все строки имеют одинаковый размер, то лучше использовать 2D-массив. Но почему вы ограничиваете его использование размерами во время компиляции? Просто используйте VLA, например. 'char (*) [len_var]' – Olaf