-1

如何避免双重释放或腐败(!prev

我有这些结构:

始终有效的空设备

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 回答