использование звездочек при объявлении массива - PullRequest
0 голосов
/ 26 января 2012

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

unsigned **(test[10]);
**(test[0]) = 5;

Как я получаю эту ошибку, когда при использовании следующего кода я не получаю сообщение об ошибке? В чем разница?

unsigned test3[10][10][10];
**(test3[0]) = 5;

Мой второй вопрос: я пытаюсь перенести часть кода, написанного для Unix, на Windows. Одна из строк такова:

unsigned **(precomputedHashesOfULSHs[nnStruct->nHFTuples]);

* nHFTuples имеет тип int, но не является константой , и это ошибка, которую я получаю;

error C2057: expected constant expression

Возможно ли, что я получаю эту ошибку, потому что я запускаю ее на Windows, а не на Unix? - и как бы я решил эту проблему? Я не могу сделать nHFTuples константой, потому что пользователь должен будет предоставить значение для этого!

Ответы [ 2 ]

3 голосов
/ 26 января 2012

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

Во втором вы правильно объявили массив, но используете его неправильно. Массивы не являются указателями, и вы не разыменовываете их.

Сделайте это:

unsigned test3[10][10][10];
test3[0][0][0] = 5;

Чтобы ответить на ваш второй вопрос, вы должны использовать число, которое во время компиляции может быть известно как размер массива. GCC имеет нестандартное расширение, которое позволяет вам это делать, но оно не переносимо и не является частью стандарта (хотя C99 ввел их). Чтобы исправить это, вам придется использовать malloc и free:

int i, j, k;

unsigned*** precomputedHashOfULSHs = malloc(nnStruct->nHFTuples * sizeof(unsigned));

for (i = 0; i < firstDimensionLength; ++i) {
    precomputedHashOfULSHs[i] = malloc(sizeOfFirstDimension * sizeof(unsigned));

    for (j = 0; j < secondDimensionLength; ++j) {
        precomputedHashOfULSHs[i][j] = malloc(sizeOfSecondDimension * sizeof(unsigned));

        for (k = 0; k < sizeOfSecondDimension; ++k)
            precomputedHashOfULSHs[i][j][k] = malloc(sizeof(unsigned));
    }
}

// then when you're done...

for (i = 0; i < firstDimensionLength; ++i) {
    for (j = 0; j < secondDimensionLength; ++j) {
        for (k = 0; k < sizeOfSecondDimension; ++k)
            free(precomputedHashOfULSHs[i][j][k]);

        free(precomputedHashOfULSHs[i][j]);
    }

    free(precomputedHashOfULSHs[i]);
}

free(precomputedHashOfULSHs);

(Простите, если этот код распределения / освобождения неправильный, уже поздно:))

1 голос
/ 26 января 2012

Хотя вы не указываете это, я думаю, что вы используете компилятор на Unix, который поддерживает C99 (такой как GCC), в то время как компилятор, который вы используете в Windows, не поддерживает его. (Visual Studio использует только C89).

У вас есть три варианта:

  1. Вы можете жестко закодировать подходящий максимальный размер массива.
  2. Вы можете выделить массив самостоятельно, используя malloc или calloc. Не забудьте освободить его, когда закончите.
  3. Перенесите программу на C ++ и используйте std :: vector.

Если вы выберете вариант 3, вам понадобится что-то вроде:

std::vector<unsigned int> precomputedHashOfULSHs;

Для одномерного вектора или для двумерного вектора используйте:

std::vector<std::vector<unsigned int> > precomputedHashOfULSHs;

Обратите внимание, что векторы по умолчанию пустые, нулевой длины, поэтому вам нужно будет добавить каждый элемент из исходного набора.

В случае test3 в качестве примера вам понадобится:

std::vector<std::vector<std::vector<unsigned int> > > precomputedHashOfULSHs;
precomputedHashOfULSHs.resize(10);
for(int i = 0; i < 10; i++) {
    precomputedHashOfULSHs[i].resize(10);
    for(int ii=0; ii<10; ii++) {
        precomputedHashOfULSHs[i][ii].resize(10);
    }
}

Я не проверял этот код, но он должен быть правильным. C ++ будет автоматически управлять памятью этого вектора.

...