#arrays #c #compiler-warnings
#массивы #c #компилятор-предупреждения
Вопрос:
Я получаю сообщение об ошибке’ предупреждение: возврат «float (*)[3]» из функции с несовместимым типом возврата » float*», когда я пытаюсь вернуть массив в функции. Я читал, что у C есть проблемы с возвратом массивов, но на самом деле не понимаю, почему и что нужно сделать, чтобы это исправить. Это мой код:
float * buildlocs(int L, int W, int H){ int c = 0, xmin, xmax, x, ymin, ymax, y, h; unsigned int nX, nY; L = L/4; W = W/4; float cellarray[16][3]; for(nX = 0; nX lt; 4;nX ) { for(nY = 0; nY lt; 4;nY ) { xmin = 0 L*(nX-1); xmax = L*nX; x = xmin rand()*(xmax-xmin); ymin = 0 W*(nY-1); ymax = W*nY; y = ymin rand()*(ymax-ymin); h = rand()*H; for(int i = 0; i lt; 3; i ){ if(i == 0){ cellarray[c][i] = x; } if(i == 1){ cellarray[c][i] = y; } if(i == 2){ cellarray[c][i] = h; } } c = c 1; } } return cellarray; }
Цель состоит в том, чтобы иметь 2d массив с 16 записями, которые содержат 3 переменные. Не мог бы кто-нибудь, пожалуйста, помочь мне исправить ошибку?
Комментарии:
1. а
float[16][3]
— это, очевидно, не аfloat*
. Это неопределенное поведение, потому что вы возвращаете локальный массив. Этот массив перестает существовать после возврата функции. Вам нужно передать данные вызывающему абоненту другим способом. Например, с помощью динамического выделения или передачи указателя на функцию в уже выделенный массив.
Ответ №1:
Есть две проблемы:
Во-первых, а float[16][3]
-это не а float*
. Во — вторых, float cellArray[16][3]
перестает существовать в конце функции-это локальная переменная, которая существует только в этой функции. когда вы возвращаете адрес массива, указатель будет указывать на что — то несуществующее-так называемый висячий указатель.
Чтобы решить проблему, вам нужно либо динамически выделить массив, либо вернуть указатель на динамически выделенный массив следующим образом (не забудьте free
сделать это, когда закончите cellArray
).:
float* cellArray = malloc(sizeof(float)*16*3); // this is one contiguous block of floats, you have to figure out how you want to index into this block, since it's stricly speaking not a two dimensional array. //...// return cellArray;
ИЛИ, что я нахожу более элегантным, это передача указателя на уже существующий массив:
void buildlocs(float* outLocs, int L, int W, int H); // added parameter to take a float* //in your function that calls buildlocs: float[16][3] cellArray; buildlocs(amp;cellArray[0],L,W,H); // pass allocated array into function, again, this is a pointer, not a two-dimensional array
Комментарии:
1. Я вроде понимаю, но что делает строка: float[16][3] cellArray; создать точно?
2. Это неинициализированный массив в автоматическом хранилище (стеке). Он перестанет существовать, как только эта функция вернется, но вы можете передавать его в функции, пока он существует.