-1

同じエラー コードに関して同様の質問をいくつか受けましたが、最も懸念されるのは無効なポインター アドレスを返すことです。ただし、返されたアドレスが何であれ、私のプログラムは正しく動作するため、ここではそうではないようです。

format_string:

static char *format_string(char *string)
{
    int i;

    if (string == NULL) {
        return string;
    }
    string[0] = (char)toupper((int)string[0]);

    111->for (i = 1; string[i] != '\0'; i++) {
        if (!isalpha(string[i-1])) {
            string[i] = (char)toupper((int)string[i]);
        } else {
            string[i] = (char)tolower((int)string[i]);
        }
        if (string[i] == '/' || string[i] == '\\') {
        string[i] = ' ';
        }
    }
    /* Remove End of string White Spaces */
    while (string[--i]==' '); string[++i]='\0';

    return string;
}

メタデータ抽出:

static int metadata_extract(const char *filename, struct kw_metadata *s)
{
    char *memchar = NULL;
    s->obj = NULL;
    s->do_cleanup = &do_on_cleanup;
    if (!is_of_type(filename)) {        
        return KW_ERROR;
    }

    TagLib_File* file = taglib_file_new(filename); 
    TagLib_Tag* tag = taglib_file_tag(file);

    s->type = strdup("Audio");
    s->tagc = 4;
    s->tagtype = (char **)malloc(4 * sizeof(char *));
    s->tagv = (char **)malloc(4 * sizeof(char *));

    memchar = strdup("title");
    s->tagtype[0] = memchar;
    memchar = strdup("artist");
    s->tagtype[1] = memchar;
    memchar = strdup("album");
    s->tagtype[2] = memchar;
    memchar = strdup("genre");
    s->tagtype[3] = memchar;

    153->memchar = strdup(taglib_tag_title(tag));
    memchar = format_string(memchar);
    s->tagv[0] = memchar;
    memchar = strdup(taglib_tag_artist(tag));
    memchar  = format_string(memchar);
    s->tagv[1] = memchar;
    memchar = strdup(taglib_tag_album(tag));
    160->memchar = format_string(memchar);
    s->tagv[2] = memchar;
    memchar = strdup(taglib_tag_genre(tag));
    memchar = format_string(memchar);
    s->tagv[3] = memchar;

    s->obj = file;
    s->do_init = &do_on_init;
    s->do_cleanup = &do_on_cleanup;

    taglib_tag_free_strings();
    taglib_file_free(file);

    return KW_SUCCESS;
}

valgrind:

==16769== Invalid read of size 1
==16769==    at 0x5317605: format_string (plugin_taglib.c:111)
==16769==    by 0x531781F: metadata_extract (plugin_taglib.c:160)
==16769==    by 0x405EB3: metadata_extract (metadata_extract.c:36)
==16769==    by 0x403351: add_metadata_file (dbbasic.c:221)
==16769==    by 0x4032D5: add_file (dbbasic.c:174)
==16769==    by 0x406485: import_semantics (import.c:97)
==16769==    by 0x406440: import_semantics (import.c:92)
==16769==    by 0x4065AC: import (import.c:127)
==16769==    by 0x401916: main (kwest_main.c:87)
==16769==  Address 0x6f4ce11 is 0 bytes after a block of size 1 alloc'd
==16769==    at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16769==    by 0x57A6D71: strdup (strdup.c:43)
==16769==    by 0x531780F: metadata_extract (plugin_taglib.c:159)
==16769==    by 0x405EB3: metadata_extract (metadata_extract.c:36)
==16769==    by 0x403351: add_metadata_file (dbbasic.c:221)
==16769==    by 0x4032D5: add_file (dbbasic.c:174)
==16769==    by 0x406485: import_semantics (import.c:97)
==16769==    by 0x406440: import_semantics (import.c:92)
==16769==    by 0x4065AC: import (import.c:127)
==16769==    by 0x401916: main (kwest_main.c:87)
4

2 に答える 2

6

for (i = 0; string[i] != '\0'; i++) {
    if (string[i-1]) {

string[-1]これは通常、サイズ 1 の無効な読み取りです。

おそらくあなたが意味した

for(i = 1; ...

編集後:

ループの前に、文字列が終了する前に少なくとも 1 文字あることを確認する必要があります。

if (string[0] == 0) return string;

(偶数の前に行うのが最善string[0] = (char)toupper((int)string[0]);です)。メッセージ

アドレス 0x6f4ce11 は、サイズ 1 のブロックが割り当てられた後の 0 バイトです。

ed 文字列の 1 つstrdupが空だったことを示します (サイズ 1 のブロックは、0 ターミネータのスペースのみが割り当てられたことを意味します)。

末尾のスペースをマークすると、

while (string[--i]==' '); string[++i]='\0';

インデックスが有効かどうかはチェックしません。文字列全体がスペースで構成されている場合は、少なくとも を読んでstring[-1]ください。次のことを確認する必要があります。

while(i-- > 0 && string[i] == ' ');
string[++i] = 0;
于 2013-02-27T18:47:47.963 に答える
0

実際に変数を使用する前に、 if (NULL != memchar)で検証してみてください。そうしないstrdupと、関数も同様に予測できない結果をもたらします。

于 2016-02-16T22:33:04.363 に答える