• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Проблемы С Глобальным Массивом

  • Автор темы SchwarzeWolfin
  • Дата начала
S

SchwarzeWolfin

есть проект на Visual Studio 2008, в файле matix.h объявляю массивы

Код:
const int M = 4;
float T[M][M],R1[4][4],R2[4][4],R3[4][4],W[4][4],V1[4][4];

extern float ttt[2];
float xx1, xx2, yy1, yy2;
float a1, a2, b1, b2;
float ms1,ms2;
float tn_x,tn_y,tn_z,vr_x,vr_y,vr_z,aA,bB,cC;



void prR2(float vx, float vz, float c[M][M]);
void prR3(float vx, float vy, float vz, float c[M][M]);
void prW(float a,float c[M][M]);

void times(float a[M][M], float b[M][M], float c[M][M]);
void timesVM(float a[M], float b[M][M], float c[M]);
void set(float a[M][M], float b[M][M]);
void homogen(float a[M], float b[M]);
void cortesian(float b[M], float a[M]);
void makeHomogenVec(float x, float y, float z, float c[M]);
void unit(float e[M][M]);
void move(float Tx, float Ty, float Tz, float c[M][M]);
void rotate(float phi, float c[M][M]);
void scale(float S, float c[M][M]);

потом я в файле Form1.h пишу например T[0][0] = 5; при этом значение элемента массива вообще никак не изменяется. но если таким же образом объявить просто переменную типа float (не массив), то всё нормально работает. подскажите пожалуйста, как исправить
 
R

rrrFer

но если таким же образом объявить просто переменную типа float (не массив), то всё нормально работает
Но не должно.
Код, который размещается в хедерах вообще не компилируется.

Но он будет скопилирован, если хедер будет включен в единицу компиляции (.cpp файл).
Поэтому глобальные переменные в хедерах объявлять вообще ненадо.

если ты объявишь глобальную переменную в 1.h, подключишь его в 2.cpp и 3.cpp - то получишь ошибку линковки, скорее всего.

Посмотри в сторону ключевого слова extern.

-----------
То, что выше, касалось объявления переменных. Теперь по инициализации.
потом я в файле Form1.h пишу например T[0][0] = 5;
Это вообще не должно работать. Смотри, гипотетически, ты инициализируешь одну и ту же глобальную переменную в нескольких файлах, что должен делать компилятор в этом случае? - какое значение ей присвоить?
Никогда так не делай. Инициализацию переменных вноси в код функций.

Инициализировать сразу можно только глобальные константы.
 
S

SchwarzeWolfin

спасибо за ответ. а изменение значения элементов массива как раз в функции и описано - в обработчике загрузки формы (FormLoad вроде), что именно здесь неверно?
 
R

rrrFer

Я не вижу кода, который не работает (если возможно - повторите ошибку на более простом примере {чтобы была только одна функция и один массив}).

И прикрепите код полностью. (тут самое главное раздел include, а вы его и вовсе не прикрепляли).

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

Еще важно знать в каком месте описана функция.

Я вроде как пытаюсь повторить твою ошибку, но мне об ошибке компилятор сообщает (все как я описывал выше):

файл 3.h:
Код:
int a;
файл 1.cpp:
Код:
#include "3.h"
файл 2.cpp:
Код:
#include "3.h"
int main() {
a = 1000;
}

Компилирую:
rrrfer@linux-2oyq:~/project> g++ 1.cpp 2.cpp -o main
/tmp/ccyrjX8E.o:(.bss+0x0): multiple definition of `a'
/tmp/ccyKLNco_O:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
rrrfer@linux-2oyq:~/project>

Причины я описал выше - в каждой единице компиляции получается своя копия глобальной переменной.
Потому что перед компиляцией происходит препроцессорная обработка, при которой все директивы include без разбора заменяются на текст файлов (которые указаны в директиве - в данном случае 3.h).

В результате после препроцессорной обработки имеем:

файл 1.cpp:
Код:
int a;
файл 2.cpp:
Код:
int a;
int main() {
a = 1000;
}

Каждый модуль (единица компиляции) компилируется отдельно в объектный файл, и все окей. Но потом наичнает работать линкер, который из объектных файлов пытается построить исполняемый файл. И тут линкер замечает, что в исполняемом файле выходит 2 глобальных переменных с одним именем - и мы получаем "странную ошибку", пример которой я привел выше.

А как делаете Вы? - как у вас получилось это: "но если таким же образом объявить просто переменную типа float (не массив), то всё нормально работает. "
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!