Вот этот класс, который я написал для решения этой проблемы:
public class CovariantIListAdapter<TBase, TDerived> : IList<TBase>
where TDerived : TBase
{
private IList<TDerived> source;
public CovariantIListAdapter(IList<TDerived> source)
{
this.source = source;
}
public IEnumerator<TBase> GetEnumerator()
{
foreach (var item in source)
yield return item;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(TBase item)
{
source.Add((TDerived) item);
}
public void Clear()
{
source.Clear();
}
public bool Contains(TBase item)
{
return source.Contains((TDerived) item);
}
public void CopyTo(TBase[] array, int arrayIndex)
{
foreach (var item in source)
array[arrayIndex++] = item;
}
public bool Remove(TBase item)
{
return source.Remove((TDerived) item);
}
public int Count
{
get { return source.Count; }
}
public bool IsReadOnly
{
get { return source.IsReadOnly; }
}
public int IndexOf(TBase item)
{
return source.IndexOf((TDerived) item);
}
public void Insert(int index, TBase item)
{
source.Insert(index, (TDerived) item);
}
public void RemoveAt(int index)
{
source.RemoveAt(index);
}
public TBase this[int index]
{
get { return source[index]; }
set { source[index] = (TDerived) value; }
}
}
Теперь вы можете написать такой код:
List<Dog> dogs = new List<Dog>();
dogs.Add(new Dog { Name = "Spot", MaximumBarkDecibals = 110 });
IEnumerable<Animal> animals = dogs;
IList<Animal> animalList = new CovariantIListAdapter<Animal, Dog>(dogs);
animalList.Add(new Dog { Name = "Fluffy", MaximumBarkDecibals = 120 });
Изменения видны в обоих списках, потому что там действительно все еще только 1 список. Класс адаптера просто передает вызовы, при необходимости накладывая элементы для достижения желаемого интерфейса IList<TBase>
.
Очевидно, что если вы добавите что-либо, кроме Dogs, в animalList
, оно выдает исключение, но это удовлетворил мои потребности.
У вас ошибка сегментации, потому что вы пишете по неинициализированному адресу в void fft(complex_num* input, complex_num* output, int n)
в строке:
output[i] = inp[i];
вывод происходит из fft2 в строка
fft(input[i], temp[i], width);
, где temp установлена
temp = (complex_num **) malloc(width * sizeof(complex_num*));
, но temp[i]
не инициализирована
Возможно, fft(input[i], temp[i], width);
должно быть fft(input[i], &temp[i], width);
в то время как fft становятся:
void fft(complex_num* input, complex_num** output, int n) {
complex_num* dummy = (complex_num *)malloc(n * sizeof(complex_num));
complex_num* inp = (complex_num *)malloc(n * sizeof(complex_num));
for (int i = 0; i < n; ++i) {
dummy[i].real = 0;
dummy[i].imag = 0;
inp[i].real = 0;
inp[i].imag = 0;
}
printf("%lf", inp[1].real);
for (int i = 0; i < n; ++i) {
dummy[i] = input[i];
inp[i] = input[i];
}
fft_driver(inp, dummy, n, 1);
printf("Hello\n");
*output = inp;
}
В любом случае в fft2 есть другая проблема в вызове:
fft(matrix[i], &temp[i], width);
, потому что инициализация matrix[i]
прокомментирована, matrix[i]
не инициализирована и в fft вы получаете доступ к неизвестным адресам в этих строках
dummy[i] = input[i];
inp[i] = input[i];
Строка //matrix[i] = (complex_num*) malloc(height * sizeof(complex_num));
не должна быть в комментарий, но также изменяющий размер выделения:
matrix[i] = (complex_num*) malloc(width * sizeof(complex_num));
и ниже строки matrix[i][j] = temp[j][i];
не должен быть в комментарии
, делая все изменения, которые выполняются (я использовал 3.1415927 для M_PI)
/tmp % ./a.out
0.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
4.0000004.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
[(8, 0), (0, 0), (0, 0), (0, 0), ]
[(4, -4), (0, 0), (0, 0), (0, 0), ]
[(0, 0), (0, 0), (0, 0), (0, 0), ]
[(4, 4), (0, 0), (0, 0), (0, 0), ]
0.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
8.0000004.0000000.0000004.0000008.0000004.0000000.0000004.0000008.0000004.0000000.0000004.0000008.0000004.0000000.0000004.0000000.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
[(1, -0), (1, -0), (1, -0), (1, -0), ]
[(1, -2.8606e-18), (1, -2.8606e-18), (1, -2.8606e-18), (1, -2.8606e-18), ]
[(0, 0), (0, -0), (0, -0), (0, -0), ]
[(0, 2.8606e-18), (0, 2.8606e-18), (0, 2.8606e-18), (0, 2.8606e-18), ]
Я не знаю, является ли это ожидаемым результатом, но по крайней мере valgrind не обнаруживает никаких незаконных м доступ к памяти и неинициализированные значения.
У вас есть утечки памяти, чтобы их устранить:
в fft2 заменить
for (int i = 0; i < height; ++i) {
fft(matrix[i], &temp[i], width);
}
на
for (int i = 0; i < height; ++i) {
free(temp[i]);
fft(matrix[i], &temp[i], width);
free(matrix[i]);
}
free(matrix);
и в конце add
for (int i = 0; i < height; ++i)
free(temp[i]);
free(temp);
В fft добавить free(dummy);
до конца
Эти изменения устраняют все утечки памяти:
/tmp % valgrind --leak-check=full ./a.out
==12924== Memcheck, a memory error detector
==12924== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==12924== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==12924== Command: ./a.out
==12924==
0.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
4.0000004.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.0000000.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
[(8, 0), (0, 0), (0, 0), (0, 0), ]
[(4, -4), (0, 0), (0, 0), (0, 0), ]
[(0, 0), (0, 0), (0, 0), (0, 0), ]
[(4, 4), (0, 0), (0, 0), (0, 0), ]
0.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
8.0000004.0000000.0000004.0000008.0000004.0000000.0000004.0000008.0000004.0000000.0000004.0000008.0000004.0000000.0000004.0000000.000000Hello
0.000000Hello
0.000000Hello
0.000000Hello
[(1, -0), (1, -0), (1, -0), (1, -0), ]
[(1, -2.8606e-18), (1, -2.8606e-18), (1, -2.8606e-18), (1, -2.8606e-18), ]
[(0, 0), (0, -0), (0, -0), (0, -0), ]
[(0, 2.8606e-18), (0, 2.8606e-18), (0, 2.8606e-18), (0, 2.8606e-18), ]
==12924==
==12924== HEAP SUMMARY:
==12924== in use at exit: 0 bytes in 0 blocks
==12924== total heap usage: 44 allocs, 44 frees, 2,688 bytes allocated
==12924==
==12924== All heap blocks were freed -- no leaks are possible
==12924==
==12924== For counts of detected and suppressed errors, rerun with: -v
==12924== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
int main()
, а не void main()
Если я добавлю весь код, чтобы помочь вам, потому что есть много изменений:
[ 1112]