Почему доступ к указателям после передачи функции вызывает ошибку сегментации? [закрыто]

Вот этот класс, который я написал для решения этой проблемы:

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, оно выдает исключение, но это удовлетворил мои потребности.

-1
задан nikhilbalwani 22 March 2019 в 13:39
поделиться

1 ответ

У вас ошибка сегментации, потому что вы пишете по неинициализированному адресу в 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)

[1151 ] Обратите также внимание, что main должно быть int main(), а не void main()


Если я добавлю весь код, чтобы помочь вам, потому что есть много изменений:

[ 1112]
0
ответ дан nikhilbalwani 22 March 2019 в 13:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: