, если final используется с объектами, вы не можете изменить ссылку на этот объект, но изменение значения отлично. Aray - это объект в java, и если вы хотите, чтобы значение объекта не изменялось, после его создания вам нужно будет сделать объект неизменным и примитивный массив нельзя сделать неизменным в java.
final int [] finalArr={5,6,8};
System.out.println("Value at index 0 is "+finalArr[0]);
//output : Value at index 0 is 5
//perfectly fine
finalArr[0]=41;
System.out.println("Changed value at index 0 is "+finalArr[0]);
//Changed value at index 0 is 41
int[] anotherArr={7,9,6};
// finalArr=anotherArr;
//error : cannot assign a value to final variable finalArr
Подробнее о неизменяемом массиве вы можете обратиться к этим ссылкам:
Предупреждение является точно правильным. Ваша функция хочет массив указателей. Вы даете ему массив массивов.
Ожидаемый:
sep_foo: +------+ +-----+ |char**|--> 0: |char*|-->"string1" +------+ +-----+ 1: |char*|-->"string2" +-----+ *sep_foo_qty-1: |... | +-----+
, Что Вы обеспечили:
sep_foo: +--------------------------------+ 0: | char[MAX_STRING_LENGTH] | +--------------------------------+ 1: | char[MAX_STRING_LENGTH] | +--------------------------------+ MAX_QTY-1: | ... | +--------------------------------+
массив с элементами типа X
может "затухнуть" в pointer-to-X
, или X*
. Но значению [1 110] не позволяют измениться в том преобразовании. Только [1 122] один операция затухания позволяются. Вам был бы нужен он для случая дважды. В Вашем случае, X
array-of-MAX_STRING_LENGTH
- символы. Функция хочет X
быть указателем на символ. Так как это не то же, компилятор предупреждает Вас. Я немного удивлен, что это было просто предупреждение начиная ни с чего хорошего, может прибыть из того, что компилятор позволил происходить.
В Вашей функции, Вы могли написать этот код:
char* y = NULL;
*sep_foo = y;
Это - свод законов, так как sep_foo
char**
, таким образом *sep_foo
char*
и так y
; можно присвоить им. Но с то, что Вы пытались сделать, *sep_foo
, не будет действительно быть char*
; это указало бы на массив символа. Ваш код, в действительности, попытался бы сделать это:
char destination[MAX_STRING_LENGTH];
char* y = NULL;
destination = y;
Вы не можете присвоить указатель в массив, и таким образом, компилятор предупреждает, что вызов бесполезен.
существует два способа решить это:
Изменение путем Вы объявляете и выделяете sep_foo
на стороне вызова, таким образом, это соответствует тому, что функция ожидает получать:
char** sep_foo = calloc(MAX_QTY, sizeof(char*));
for (int i = 0; i < MAX_QTY; ++i)
sep_foo[i] = malloc(MAX_STRING_LENGTH);
или, эквивалентно
char* sep_foo[MAX_QTY];
for (int i = 0; i < MAX_QTY; ++i)
sep_foo[i] = malloc(MAX_STRING_LENGTH);
Изменение прототип функции для принятия то, что Вы действительно даете ему:
int parse(const char *foo, char sep_foo[MAX_QTY][MAX_STRING_LENGTH], int *sep_foo_qty);
Параметр 2 должен быть
char sep_foo[][MAX_STRING_LENGTH]
Для разъяснения, Вы передаете указатель на синтаксический анализ () и рассматриваете его как указатель на указатель. Многомерный массив в C НЕ является массивом указателей. Это - единственный блок памяти, на которую указывает переменная типа массив. Вы не можете разыменовать его дважды.
sep_foo
определяется как массив массивов. Другими словами, когда Вы используете sep_foo
, это указывает на начало последовательной памяти. Вот модель:
(assume MAX_STRING_LENGTH = 16, MAX_QTY = 2)
sep_foo = &&0000
sep_foo[0] = &0000
sep_foo[0][0] = *&0000 = 12
sep_foo[0][8] = *&0008 = 74
sep_foo[1] = &0010
sep_foo[1][0] = *&0010 = 12
0000 12 34 56 78 9A BC DE F0 74 10 25 89 63 AC DB FE
0010 12 34 56 78 9A BC DE F0 74 10 25 89 63 AC DB FE
Однако Ваша функция ожидает массив указателей (на самом деле, указателя на указатель). Это смоделировано как таковое:
sep_foo_arg = &&0000
sep_foo_arg[0] = *&&0000 = &0010
sep_foo_arg[0][0] = *&*&0000 = 12
sep_foo_arg[0][8] = *(&*&0000 + 8) = 74
sep_foo_arg[1] = *&&0002 = &0020
sep_foo_arg[1][0] = *&*&0000 = 12
0000 0010 0020 xxxx xxxx xxxx xxxx xxxx xxxx
0010 12 34 56 78 9A BC DE F0 74 10 25 89 63 AC DB FE
0020 12 34 56 78 9A BC DE F0 74 10 25 89 63 AC DB FE
Да... Синтаксис может немного сбивать с толку мои объяснения...
Так или иначе, можно решить эту проблему путем сообщения функции, как рассматривать указатель, указал. В частности, Вы хотели бы рассматривать его как массив (последовательность памяти):
int parse(const char *foo, char (*sep_foo)[MAX_STRING_LENGTH], int *sep_foo_qty);
Если это - Ваш точный код, то я предполагаю, что segfault из-за того, что Вы не выделили память char* token
внутренняя часть Ваша функция синтаксического анализа и затем использование это в Вашем strcpy.