Если Вы используете Linux + Sun JDK/JRE 32 бита , изменяете "-vm" на:
-vm
[your_jdk_folder]/jre/lib/i386/client/libjvm.so
при использовании Linux + Sun JDK/JRE 64 бита измените "-vm" на:
-vm
[your_jdk_folder]/jre/lib/amd64/server/libjvm.so
Это хорошо работает для меня на Ubuntu 8.10 и 9.04
В коде:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
return array;
}
вы выделяете место для двух элементов в массиве и устанавливаете array
так, чтобы он указывал на первый:
+-------+ +----------+
| array | ---> | array[0] |
+-------+ +----------+
| array[1] |
+----------+
Затем вы увеличиваете указатель элемента с array ++
и , что - это то, что возвращается вызывающей функции в конце. Этот указатель указывает на второй элемент массива , поэтому он кажется неправильным (и почему вы почти наверняка вылетите, когда попытаетесь освободить эту память позже):
+-------+ +----------+
| array | -+ | array[0] |
+-------+ | +----------+
+-> | array[1] |
+----------+
Что вам нужно, так это :
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array[0].name = strdup("Robert");
array[1].name = strdup("Jose");
return array;
}
как вы уже указали. Это решение не вообще изменяет указатель массива
. Но если вы действительно хотите использовать указатели, вы можете просто отменить действия массива ++
с помощью массива -
перед возвратом, чтобы массив
был установлен обратно на правильное значение:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
array--;
return array;
}
Или, другой способ, который не изменяет исходный указатель, не использует индексацию массива и не использует второй указатель, - использовать арифметику указателя. Компилятор знает, на какой тип указывает указатель, поэтому может правильно настроить указатель, чтобы найти следующий элемент (вы уже знаете, что он знает, как это сделать, поскольку array ++
является сокращением для array = array + 1
, и этот оператор также корректирует значение на правильную величину):
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
(array+0)->name = strdup("Robert");
(array+1)->name = strdup("Jose");
return array;
}
Вы просто выполняете простые арифметические операции с указателями, такие как сложение и вычитание:
array->name = "Robert";
(array+1)->name = "Jose";
return array;
Указатель - это буквально просто число (адрес в памяти). Вы изменяете этот указатель так, чтобы он указывал на другое место, а затем возвращаете его.
Это будет использовать арифметику указателя и сохранить исходный указатель массива:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
(array+0)->name = strdup("Robert");
(array+1)->name = strdup("Jose");
return array;
}
Поскольку вы увеличили массив
, у вас больше нет указателя на элемент [0]
, а есть указатель на элемент [1]
. Сделайте следующее:
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
return array - 1;
Имейте в виду, что в C p [x]
не более чем * (p + x)
, или, если хотите, подумайте об этом : (p + x) [0]
. Последний случай - это то, что ваша программа эффективно выполняла с x
== 1. Итак, (p + 1) [1]
то же самое, что p [2]
, и там ничего нет, отсюда ваш нулевой результат.
(Вы также можете записать это как ...
array++->name = strdup("Robert");
array--->name = strdup("Jose");
return array;
... но если вы это сделаете, группа людей придет и проголосует против вас. это действительно так сложно читать? Действительно наша цель - писать только скучный, неуклюжий код?)