glibc обнаружил ошибку - id3Tag

Итак, я новичок в C, и я пытался написать этот инструмент для редактирования тегов id3 в музыкальных файлах из командной строки. Я получаю эту ошибку:

* glibc обнаружил двойное освобождение или повреждение (вверху): 0x0000000000502010 **

Из того, что я читал, я знаю, что это как-то связано с освобождением памяти. Я просто не совсем уверен, куда идти отсюда. Во всяком случае, моя логика заключалась в том, что если бы тег существовал, я бы прочитал этот тег, а затем внес все необходимые изменения в поля, указанные в командной строке. Вот блок, который доставлял мне неприятности. Заранее спасибо за любую информацию!

    fopen(argv[1], "rb");
    fseek(in_file, -128, SEEK_END);
    fread(&tagTest, sizeof(struct iD3Tag), 1, in_file);
    fclose(in_file);

    for (x = 2; x < argc-1; x++)
    {            
        if (strcmp(argv[x], "-title"))
            strncpy(tagTest.title, argv[x+1], 30);
        if (strcmp(argv[x], "-artist"))
            strncpy(tagTest.artist, argv[x+1], 30);
        if (strcmp(argv[x], "-album"))
            strncpy(tagTest.album, argv[x+1], 30);
        if (strcmp(argv[x], "-year"))
            strncpy(tagTest.year, argv[x+1], 4);
        if (strcmp(argv[x], "-comment"))
            strncpy(tagTest.comment, argv[x+1], 28);
        if (strcmp(argv[x], "-track"))
            tagTest.track = atoi(argv[x+1]);
    }

    tagTest.seperator = 0;

    fopen(argv[1], "r+b");
    fseek(in_file, -128, SEEK_END);
    fwrite(&tagTest, sizeof(struct iD3Tag), 1, in_file);
    fclose(in_file);

person soflaz    schedule 05.02.2012    source источник
comment
fread(&tagTest, sizeof(struct iD3Tag), 1, in_file); нельзя. Структуры имеют внутреннее заполнение между элементами структуры из-за ограничений выравнивания памяти, поэтому информация вашего тега будет существенно повреждена...   -  person    schedule 05.02.2012
comment
Какое определение для struct iD3Tag?   -  person pmg    schedule 05.02.2012


Ответы (1)


В этом коде нет вызовов free, поэтому я полагаю, вы довольны тем, что ничего не освобождаете дважды? Поэтому я предполагаю, что у вас есть некоторая порча кучи. т.е. вы записываете в тег больше данных, чем есть места.

Во-первых, чтобы ответить на вопрос @H2CO3, я не верю, что проблема здесь. Может случиться так, что проблема, о которой он упоминает, действительно существует — в этом случае вы испортите свой файл данных — но не похоже, что это причина сбоя программы.

Я думаю, ваша настоящая проблема в том, что вы никогда ничего не назначаете in_file! Я думаю, вам нужно:

in_file = fopen (argv[1], "rb");

Некоторые другие комментарии:

  • strcmp возвращает ноль (false), когда строка совпадает, и ненулевое значение (true), если она не соответствует... поэтому все ваши сравнения кажутся неверными - это не должно вызывать искажений.
  • Кажется, что цикл проверяет значения аргументов, а также переключатели - их следует пропустить.
  • Нет необходимости открывать файл дважды — вы можете открыть его как для чтения, так и для записи в начале.
  • Вам нужно гораздо больше проверять ошибки на случай, если файл не существует или не соответствует вашим ожиданиям, но я уверен, что вы это знали.
person ams    schedule 05.02.2012
comment
Большое спасибо! Я даже не понял, что насчет strcmp или fopen (свидетельство того, насколько я неопытен в C). Просто еще один вопрос, что именно вы имеете в виду, когда говорите, что цикл проверяет значения аргументов, а также переключается? Кроме того, я внес изменения в операторы if, но теперь у меня возникает ошибка сегментации всякий раз, когда я дважды запускаю программу в одном и том же файле. И когда я перехожу к просмотру тега после того, как отредактировал его при втором запуске программы, он не печатает все целиком. - person soflaz; 06.02.2012
comment
Представьте, что у вас есть аргументы -title foo -artist bar. Ваш код сначала проверяет, является ли -title опцией; это так, что он делает правильную вещь (или это было бы, если бы у вас был правильный strcmp). Следующее, что он делает, это проверяет, является ли foo опцией, но на самом деле она уже должна была это использовать. - person ams; 06.02.2012
comment
Ой. Теперь я понимаю. Еще раз спасибо. У меня все работает так, как должно, наконец, ха-ха - person soflaz; 07.02.2012