Возврат массива структур с помощью указателей

Если Вы используете 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

5
задан ZPS 29 November 2009 в 02:35
поделиться

5 ответов

В коде:

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;
}
18
ответ дан 18 December 2019 в 06:50
поделиться

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

    array->name = "Robert";
    (array+1)->name = "Jose";
    return array;
2
ответ дан 18 December 2019 в 06:50
поделиться

Указатель - это буквально просто число (адрес в памяти). Вы изменяете этот указатель так, чтобы он указывал на другое место, а затем возвращаете его.

1
ответ дан 18 December 2019 в 06:50
поделиться

Это будет использовать арифметику указателя и сохранить исходный указатель массива:

person * setName() {
       person * array;

       array = malloc (2 * sizeof(person));
       (array+0)->name = strdup("Robert");
       (array+1)->name = strdup("Jose");

       return array;
}
1
ответ дан 18 December 2019 в 06:50
поделиться

Да


Поскольку вы увеличили массив , у вас больше нет указателя на элемент [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;

... но если вы это сделаете, группа людей придет и проголосует против вас. это действительно так сложно читать? Действительно наша цель - писать только скучный, неуклюжий код?)

1
ответ дан 18 December 2019 в 06:50
поделиться
Другие вопросы по тегам:

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