Я пишу программу для создания серого изображения (image
) с использованием расчетов на данных, хранящихся в исходном массиве (hist
). Данные, хранящиеся в исходном массиве, сбрасываются в ноль после вызова calloc для изображения.
func1(){
float * hist = (float *) calloc(256, sizeof(float));
// operation to populate 'hist'
for...{
for...{
hist.....
}
}
hist2img(hist);
free(hist);
return 0;
}
hist2img(hist){
cout << "-> " << hist [4 * 250] << endl;
unsigned char * image = (unsigned char *) calloc(256 * 256, sizeof(unsigned char));
cout << "-> " << hist [4 * 250] << endl;
free(image);
return 0;
}
выход:
-> 0.997291
-> 0
Что происходит с данными? Все элементы в hist
0 после инструкции calloc. я нуждаюсь image
быть инициализирован до 0.
--(~$)--> gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
--(~$)--> uname
Linux 4.7.2-040702-generic x86_64 x86_64 x86_64 GNU/Linux
Вы выделяете 256 поплавков:
float * hist = (float *) calloc(256, sizeof(float));
и вы получите доступ к 1000-му элементу, который является UB
cout << "-> " << hist [4 * 250] << endl;
Вызов calloc обнуляет некоторую память, на которую вы ошибочно указали
Чтобы получить доступ к 250-му элементу поплавка hist
, просто
cout << "-> " << hist [250] << endl;
(поскольку hist
указатель на float
компилятор вычисляет адреса путем умножения размера с плавающей запятой, нет необходимости делать это самостоятельно)
Если вы знаете размер заранее, еще лучше распределить данные статически
объявление:
float hist[256]={0};
При определении hist2img
:
hist2img(float hist[256]){
в этом случае вы получаете предупреждение, когда статический индекс выходит за пределы диапазона (но все равно вылетает / UB, если какой-то переменный индекс выходит за пределы: нет проверок во время выполнения)
Других решений пока нет …