Почему этот указатель не работает? - PullRequest
0 голосов
/ 24 августа 2010

РЕДАКТИРОВАТЬ: начальный "плавать ** плавает;"была опечатка, исправлена.Также "* floats [0] = 1.0;"работает, но "* floats [1] = 1.0;"Сегфаулс в этот момент.Массив является неправильным.Компиляция не имеет предупреждений о педантичном c99.

Это сработало:

(псевдо:)

void func(int*);
int i;
func(&i);
void func(int* i) {
 func2(i);
}
void func2(int* i) {
 *i = 2;
}

начальное значение изменено на 2.

, ноне работал:

void func(float**);
float* floats;
func(&floats);
void func(float** floats) {
 func2(floats);
}
void func2(float** floats) {
 *floats[1] = 1.0;
}

сегментация по заданию;

Ответы [ 3 ]

3 голосов
/ 24 августа 2010

потому что «плавает» - плохой указатель. Конечно, вы объявили указатель, но не распределили память, поэтому, где бы она ни находилась, указатель будет недействительным.

Кроме того, адрес с плавающей точкой ** является плавающей точкой ***, а это не то, что требует ваша функция.

1 голос
/ 24 августа 2010

Почему вы передаете указатель на массив? Вы пробовали

func(float *floats)
{
  func2(floats);
}

func2(float *floats)
{
  floats[0] = 2;
}
0 голосов
/ 24 августа 2010

Скажем, у вас есть эти 2 функции, которые вы опубликовали:

void func2(float** floats) {
 *floats[1] = 1.0;
}
void func(float** floats) {
 func2(floats);
}

Тогда у вас есть следующий код:

float* floats;
func(&floats);

Что происходит? Во-первых, floats - это float *, и, поскольку он не назначен, он указывает на случайную ячейку памяти, скажем, 0xBADD. Если вы напишите сюда, вы наверняка что-то напортачите.

Адрес floats, &floats - это еще одна ячейка памяти, указывающая, где она находится в стеке, скажем, 0x1000. Это передается в func, который затем дословно передается в func2.

Что делает func2? Он пытается что-то написать в локации *floats[1]. Я не уверен, что произойдет сначала, скобка или звезда, поэтому давайте рассмотрим оба случая:

*(floats[1]): Сначала вы обнаружите, что такое floats[1]. Поскольку floats - это ячейка памяти исходной переменной floats, это 0x1000. floats[1] будет 0x1004, так как указатели имеют ширину 4 байта при условии 32-битной системы. Затем вы пытаетесь разыменовать этот указатель, который является значением того, что находится в ячейке памяти 0x1004. Это может быть что угодно, например, 0xBAD2, поэтому попытка записать значение с плавающей запятой, скорее всего, приведет к segfault.

(*floats)[1]. Вот вам первая разыменование floats, которое дает вам 0xBADD, типа float *. Затем вы пытаетесь записать значение в 0xBADD + 4 или 0xBAE1. Это память, которая не была выделена для вас, поэтому запись в нее, скорее всего, приведет к segfault.

В любом случае, вы возитесь с памятью, которая не принадлежит вам, что приводит к segfault.

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