указатели и массивы с ++ - PullRequest
       2

указатели и массивы с ++

1 голос
/ 10 сентября 2011
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

int width = 100;
int height = 100;

float cam[] = {-1.1,-1.0,1.2};
float D[] = {0.2,0.2,-0.2};
float U[] = {0.0,1.0,0.0};

float* cross(float* v1,float* v2)
{
    float el1[] = {(v1[1]*v2[2]-v1[2]*v2[1]),(v1[2]*v2[0]-v1[0]*v2[2]),(v1[0]*v2[1]-v1[1]*v2[0])};
    return el1;
}

float* neg3(float* v)
{
    float arr[3];
    for(int i=0;i<3;i++)
    arr[i] = 0.0-(v[i]);

    return arr;
}

/*

float* cam_space(float* p)
{
    float* e1 = cross(D,U);
    float* e2 = cross(D,cross(U,D));
    float* e3_n = D;

    float ar[4];
    ar[0] = e1[0]*p[0]+e1[1]*p[1]+e1[2]*p[2];
    ar[1] = e2[0]*p[0]+e2[1]*p[1]+e2[2]*p[2];
    ar[2] = -(e3_n[0]*p[0]+e3_n[1]*p[1]+e3_n[2]*p[2]);
    ar[3] = p[3];
    return ar;
}

*/
float* translate(float* p,float* v)
{

    float arr1[3];
    for(int i=0;i<=2;i++)
    arr1[i] = p[i] + v[i];

    return arr1;
}


int main()
{
    float* poi;
    poi = cam;   //undo later

    float* nc;
    nc = neg3(cam);
    cout<<" "<<nc[0]<<" "<<nc[1]<<" "<<nc[2]<<endl;


    float arbit[3] = {0.1,0.1,0.1};

    float* temp1;
    temp1 = translate(poi,arbit);
    //float* temp2;
    //temp2 = cam_space(temp);

    cout<<" "<<nc[0]<<" "<<nc[1]<<" "<<nc[2]<<endl;
    cout<<" "<<poi[0]<<" "<<poi[1]<<" "<<poi[2]<<endl;


    cout<<" "<<temp1[0]<<" "<<temp1[1]<<" "<<temp1[2]<<endl;
    return 0;
}

Как видите, я вывожу nc дважды. Но оба значения отличаются. Во второй раз отображается nc, оно фактически показывает значение temp1, а temp1 фактически показывает значения мусора. Любая помощь?

Ответы [ 4 ]

5 голосов
/ 10 сентября 2011
float* translate(float* p,float* v)
{

    float arr1[3];
    for(int i=0;i<=2;i++)
    arr1[i] = p[i] + v[i];

    return arr1;
}// arr1 ceases to exist from this point.

Вы возвращаете ссылку на локальную переменную, arr1.Он находится в стеке и освобождается при возврате вызова функции.Но вы держите ссылку на него, которая дает вам мусорные значения.Вместо new new[] arr1 и верните его.Не забудьте delete[], когда закончите.

1 голос
/ 10 сентября 2011

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

Учтите это:

struct V3 { float data[3]; }

V3 neg3(V3 v)
{
    for(int i=0;i<3;i++)
      v.data[i] = -v.data[i];
    return v;
}
1 голос
/ 10 сентября 2011

Вы возвращаете указатели на локальные переменные слева направо и по центру. Эти переменные выходят из области видимости в конце тела функции, и результатом является неопределенное поведение.

Хороший способ обработки функций изменения массива - передать массив в качестве параметра:

void modify_me(float arr[])  // or `modify_me(float * arr)`, same thing
{
  arr[0] = 0.5;
  arr[1] = -2.25;
}

int main()
{
  float myarray[2];
  modify_me(myarray);  // now myarray[0] == 0.5, etc.

  // ...
}

Поскольку вы находитесь в C ++, вы можете даже использовать шаблон магии:

template <unsigned int N>
void modify_me(float (&arr)[N])
{
  static_assert(N == 3, "You're doing it wrong!");  // C++11 feature
  arr[0] = /* ... */
}

Теперь вы получите ошибку во время компиляции, если попытаетесь вызвать ее с помощью чего-либо, что не является автоматическим массивом размера 3.

1 голос
/ 10 сентября 2011

translate() возвращает локальный указатель (преобразованный из типа массива). То, на что ссылается temp1, не существует после того, как функция translate() вернется.

То же самое относится и к neg3().

Если вы используете C ++, std::vector<float> решит все такие проблемы.

Вы могли бы написать это:

std::vector<float> translate(const std::vector<float> & p, const std::vector<float> & v)
{
   std::vector<float> vf(3);
   for(int i=0;i <3;i++)
      vf[i] = p[i] + v[i];
   return vf; //semantically, it returns a copy of the local object.
}

Аналогично, используйте std::vector везде, где вы используете float[3]. И не используйте глобальные переменные.

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