Я пытаюсь создать обобщенную функцию в C, которая принимает 2D-массив ЛЮБОГО типа и копирует его в смежный блок памяти. (Мне нужна эта функция для агрегированных операций с MPI на моих сложных типах данных).Рассеянный 2D-массив для непрерывного преобразования 2D-массива (в C)
Представьте себе У меня есть следующий целочисленный массив
int n = 5;
int m = 6;
int** int_array = (int**) malloc(n* sizeof(int*));
for (int i = 0; i < n; i++)
int_array[i] = (int *) malloc(m * sizeof(int));
В этом типе распределения памяти один не может, в принципе, надеюсь, чтобы получить доступ к, скажем, I, J-й ввод int_array с использованием следующих указателей арифметика
int value = (*lcc)[i*m+j];
Поэтому я реализовал функцию, которая в основном выделяет новый блок памяти и аккуратно упорядочивает записи int_array, чтобы работа над этим индексом работала.
void linearize(char*** array, int n, int m,unsigned int size_bytes){
char* newarray = (char*)malloc(m*n*size_bytes);
//copy array!
for (int i = 0;i<n;i++)
for(int j = 0;j<m*size_bytes;j++)
{
newarray[i*m*size_bytes+j] = (*array)[i][j];
}
//swap pointers and free old memory!
for (int i = 0;i<n;i++)
{
char * temp = (*array)[i];
(*array)[i] = newarray + i*m*size_bytes ;
free(temp);
}
}
Я хотел сделать вышеуказанную функцию для работы с любым типом типа массива, поэтому я использовал полукокс указателей делать операции побайтны. Я тестировал функцию, и пока она работает, но я не уверен в освобождении памяти.
Свободно (temp) освобождает всю память, на которую указывает int_array [i], то есть байты m * sizeof (int), доступные из int_array [i] или только первые m байтов (так как он считает, что наш массив имеет тип char, а не in)? Или просто введите: «Ли линеаризованная функция вызывает утечку памяти?»
Спасибо заранее!
* EDIT *
Как предложил Николя Барбе, я побежал VALGRIND проверки на наличие утечек памяти и не нашли.
Так суммировать основные моменты, которые я нашел трудно понять, о поведении программы были:
в функции линеаризации делает следующий код вызвать утечку памяти:
char * temp = (*array)[i];
(*array)[i] = newarray + i*m*size_bytes ;
free(temp);
НЕТ !! каким-то образом компилятор gnu достаточно умен, чтобы знать, сколько байтов указало на «temp», чтобы освободить. Первоначально я боялся, что если я array [i] является указателем типа int, например, который указывает на ячейку памяти с указанием 5 ints = 5 * 4 байта, free (temp) освободит только первые пять байтов этой памяти.
Еще один момент, чтобы сделать следующее: как освободить уже линеаризованный массив? то есть, если у вас есть:
// first initialize the array.
int** array = (int**)malloc(5*sizeof(int*);
for(int i = 0; i< 5;i++)
array[i] = (int*) malloc(5*sizeof(int));
//now a call to linearize
linearize(&array,5,5,sizeof(int));
... do some work with array ....
// now time to free array
free(array[0]);
free(array);
//suffices to free all memory pointed to by array[i] and as well as the memory allocated
// for the pointers.
Спасибо за обсуждение и предложения.
Не отвергни возвращаемое значение 'таНос()'. - кроме этого: называть 'free()' ровно один раз на 'malloc()', тогда утечек не будет. –
Это не двумерный массив. Это массив указателей на массивы. Они не одинаковы. И вы не хотите быть [трехзвездочным программистом] (http://c2.com/cgi/wiki?ThreeStarProgrammer), если можете вообще этого избежать. (и вы можете). – WhozCraig
Вы имеете в виду вместо char * temp = (char *) (* array) [i]; char * temp = (* array) [i]; ? – kennywise