-1

二重解放または破損を回避する方法 ( !prev)

私はこれらの構造体を持っています:

常に機能する null デバイス

static struct mixer null_mixer = {
    .set_device = null_set_device,
    .close_device = null_close_device,
};

利用可能なすべてのアクセス方法のリスト。弱いシンボルを使用: NULL はリンクされません。

static struct mixer *mixers[] = {
    &alsa_mixer,
    &oss_mixer,
    &null_mixer
};

実際のアクセス方法。

struct mixer *mixer = &null_mixer;

ミキサー デバイスとチャンネルを設定します。成功するまで、各アクセス方法を試してください。

void mixer_set_device( const char *devname )
{
    int i;
    mixer->close_device();
    for (i = 0; i < sizeof(mixers)/sizeof(mixers[0]); i++) {
        mixer = mixers[i];
        if (!mixer)
            continue;
        if (mixer->set_device(devname) == 0)
            break;
    }
}

ユーザーが gtk エントリでミキサーに間違った値を挿入しようとすると、次のエラーが発生します。

double free or corruption (!prev): 0x0000000002518c00 ***

ここに問題があると思います:

static void alsa_open_mixer( void )
{
    int err;
    static snd_mixer_selem_id_t *sid = NULL;
    if ((err = snd_mixer_open (&handle, 0)) < 0) {
            return;
    }
    if ((err = snd_mixer_attach (handle, card)) < 0) { # memory leak
            goto error;
    }
    if ((err = snd_mixer_selem_register (handle, NULL, NULL)) < 0) {
            goto error;
    }
    if ((err = snd_mixer_load (handle)) < 0) {
            goto error;
    }
    snd_mixer_selem_id_malloc(&sid);
    if (sid == NULL)
            goto error;
    snd_mixer_selem_id_set_name(sid, channel);
    if (!(elem = snd_mixer_find_selem(handle, sid))) {
            goto error;
    }
    if (!snd_mixer_selem_has_playback_volume(elem)) {
            goto error;
    }
    snd_mixer_selem_get_playback_volume_range(elem, &alsa_min, &alsa_max);
    if ((alsa_max - alsa_min) <= 0) {
            goto error;
    }
    snd_mixer_selem_id_free(sid);
    return;

error:
    if (sid)
            snd_mixer_selem_id_free(sid); /* THIS LINE */
    if (handle) {
            snd_mixer_close(handle);
            handle = NULL;
    }
    return;
}

static int alsa_set_device( const char *devname )
{
    int i;

    if (card) free(card);
    card = strdup( devname );
    if( !card ) return -1;

    i = strcspn( card, "/" );
    if( i == strlen( card ) ) {
        channel = "Line";
    } else {
        card[i] = 0;
        channel = card + i + 1;
    }
    alsa_open_mixer();
    if (!handle) {
        return -1;
    }
    return 0;
}

struct mixer alsa_mixer = {
    .set_device = alsa_set_device,
    .close_device = alsa_close_device,
};

二重解放または破損 ( !prev): 0x0000000002518c00 *

アップデート:

問題のある行を示します

4

1 に答える 1

-1

私が見ることができるように、あなたはLinuxの下で働いています。次に、メモリの問題を見つけるために valgrind を使用できます。

于 2013-09-14T18:50:10.923 に答える