не удалось записать правильные значения в указатель массива typedef - PullRequest
0 голосов
/ 07 декабря 2011

Моя проблема в следующем - у меня есть следующие строки кода:

// allocate a new vector
        Vector3I *theVector = (Vector3I*)calloc(1,sizeof(Vector3I));

        // write face's points to this vector
        *theVector[0] = a3dsFace->points[0];
        *theVector[1] = a3dsFace->points[1];
        *theVector[2] = a3dsFace->points[2];

В массиве points[] находятся значения {0,1,2}.Когда я пишу их в Vector3I, на который я указываю, я получаю {0,0,0}.Есть ли у вас какие-либо предложения о том, что я делаю неправильно?

РЕДАКТИРОВАТЬ: Некоторые дополнительные сведения:

Это из lib3ds в: http://code.google.com/p/lib3ds/

struct Lib3dsFace {
    Lib3dsUserData user;    /*! Arbitrary user data */
    char material[64];      /*! Material name */
    Lib3dsWord points[3];   /*! Indices into mesh points list */
    Lib3dsWord flags;       /*! See Lib3dsFaceFlag, below */
    Lib3dsDword smoothing;  /*! Bitmask; each bit identifies a group */
    Lib3dsVector normal;
};

a3dsFace - это структура Lib3dsFace.

И массив точек этого типа:

 typedef unsigned __int16 Lib3dsWord

И мой указатель:

Vector3I* theVector

равен

typedef int Vector3I[3];

Я надеюсь, что этопринесет некоторый свет к проблеме.

С уважением.

Ответы [ 3 ]

2 голосов
/ 07 декабря 2011

Код ниже работает и проверяет ваш фрагмент кода. Если что-то не работает, было бы неплохо создать такой тест с жестко заданными значениями для *a3dsFace, чтобы сузить вашу проблему.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef int Vector3I[3];
typedef uint16_t Lib3dsWord;

struct Lib3dsFace {
   /* ... */
   Lib3dsWord points[3];   /*! Indices into mesh points list */
   /* ... */
};

/* ... */
struct Lib3dsFace some_face = { {0, 1, 2} };
struct Lib3dsFace *a3dsFace = &some_face;
/* ... */

int main(void)
{
   Vector3I *theVector = (Vector3I*)calloc(1,sizeof(Vector3I));

   (*theVector)[0] = a3dsFace->points[0];
   (*theVector)[1] = a3dsFace->points[1];
   (*theVector)[2] = a3dsFace->points[2];

   printf("theVector: %p, *theVector: %p, &(*theVector)[0]: %p\n", theVector, *theVector, &(*theVector)[0]);

   printf("RIGHT Addresses: %p, %p, %p\n", &(*theVector)[0], &(*theVector)[1], &(*theVector)[2]);
   printf("WRONG Addresses: %p, %p, %p\n", &*theVector[0], &*theVector[1], &*theVector[2]);

   printf("Values: %d, %d, %d\n", (*theVector)[0], (*theVector)[1], (*theVector)[2]);

   free(theVector);

   return 0;
}

Выход:

theVector: 0x1cd3010, *theVector: 0x1cd3010, &(*theVector)[0]: 0x1cd3010
RIGHT Addresses: 0x1cd3010, 0x1cd3014, 0x1cd3018
WRONG Addresses: 0x1cd3010, 0x1cd301c, 0x1cd3028
Values: 0, 1, 2

Я разместил адреса там, чтобы вы могли видеть, что (*theVector)[0] является допустимым способом доступа к первому элементу вашего динамически выделенного Vector3I.

Возможно, вы не установили a3dsFace->points правильно, и именно поэтому {0, 0, 0} копируется. Также обратите внимание, что у вас есть каждый элемент Vector3I типа int, а каждая точка имеет тип uint16_t. Вам также не нужно использовать calloc для обнуления выделенной памяти, поскольку вы сразу после назначения им значений; Вы можете просто использовать malloc.

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

РЕДАКТИРОВАТЬ: У меня случайно было *theVector[0], которое должно было быть и сейчас (*theVector)[0], поскольку [] имеет более высокий приоритет, чем *. В противном случае это вызвало бы неопределенное поведение из-за того, что вы пересекаете границы массива, мой плохой. Я не знаю, как я забыл, что, когда это было одной из главных причин, я собирался опубликовать ответ, прежде чем вы сделали свое редактирование. Это сработало, но если вы запустили его через такую ​​программу, как valgrind, вам бы сказали, что что-то было не совсем правильно (даже если бы он работал так, как ожидалось).

Как вы можете видеть по адресам, приведенным выше, есть большая разница. Например, наличие *theVector[1], которое из-за приоритета оператора совпадает с *(theVector[1]), будет означать, что оно будет увеличивать адрес, на который указывает theVector, на 3 * sizeof(int) байт (он же sizeof(Vector3I)), вместо 1 * sizeof(int) в (правильном) случае (*theVector)[1]).

2 голосов
/ 07 декабря 2011

попробуйте это (обратите внимание, выделите 3 элемента и получите доступ только с помощью записи массива):

Vectore3I *theVector = (Vector3I*)calloc(3, sizeof(Vector3I));

theVector[0] = a3dsFace->points[0];
theVector[1] = a3dsFace->points[1];
theVector[2] = a3dsFace->points[2];
1 голос
/ 07 декабря 2011

Как насчет этого:

// allocate a new vector
        Vector3I *theVector = calloc(1,sizeof(Vector3I));

        // write face's points to this vector
        (*theVector)[0] = a3dsFace->points[0];
        (*theVector)[1] = a3dsFace->points[1];
        (*theVector)[2] = a3dsFace->points[2];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...