1

我编写了一个简单的代码来从当前目录中获取所有文件名并将它们保存到 char **array 中。但是我的代码给了我分段错误和一些 valgrind 错误。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glob.h>

char **getFilenames()
{
    char **filenames = NULL;
    glob_t data;
    unsigned int i;

    switch( glob("./*.*", 0, NULL, &data ) )
    {
        case 0:
            break;
        case GLOB_NOSPACE:
            printf( "Out of memory\n" );
            break;
        case GLOB_ABORTED:
            printf( "Reading error\n" );
            break;
        case GLOB_NOMATCH:
            printf( "No files found\n" );
            break;
        default:
            break;
    }

    filenames = malloc(sizeof(char*)*data.gl_pathc);
    for(i=0; i<data.gl_pathc; i++)
    {
        filenames[i] = data.gl_pathv[i];
    }
    globfree( &data );
    return filenames;
}

int main( int argc, char *argv[] )
{
    char **filenames = getFilenames();
    unsigned int i = 0;
    for(i=0; filenames[i] != NULL; i++)
    {
        printf("%s\n", filenames[i]);
    }

    free(filenames);

    return 0;
}

Valgrind 的输出:

==3936== Invalid read of size 8
==3936==    at 0x40077F: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5207670 is 0 bytes after a block of size 608 alloc'd
==3936==    at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4006C9: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== FILE DESCRIPTORS: 3 open at exit.
==3936== Open file descriptor 2: /dev/pts/3
==3936==    <inherited from parent>
==3936== 
==3936== Open file descriptor 1: /dev/pts/3
==3936==    <inherited from parent>
==3936== 
==3936== Open file descriptor 0: /dev/pts/3
==3936==    <inherited from parent>
==3936== 
==3936== 
==3936== HEAP SUMMARY:
==3936==     in use at exit: 0 bytes in 0 blocks
==3936==   total heap usage: 155 allocs, 155 frees, 35,964 bytes allocated
==3936== 
==3936== All heap blocks were freed -- no leaks are possible
==3936== 
==3936== ERROR SUMMARY: 2204 errors from 12 contexts (suppressed: 2 from 2)
==3936== 
==3936== 1 errors in context 1 of 12:
==3936== Invalid read of size 8
==3936==    at 0x40077F: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5207670 is 0 bytes after a block of size 608 alloc'd
==3936==    at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4006C9: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 13 errors in context 2 of 12:
==3936== Invalid read of size 8
==3936==    at 0x4EC13A3: __GI_mempcpy (memcpy.S:123)
==3936==    by 0x4EAEB11: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1329)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5205b7a is 10 bytes inside a block of size 19 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 13 errors in context 3 of 12:
==3936== Invalid read of size 8
==3936==    at 0x4EC13A0: __GI_mempcpy (memcpy.S:122)
==3936==    by 0x4EAEB11: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1329)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5205b72 is 2 bytes inside a block of size 19 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 16 errors in context 4 of 12:
==3936== Invalid read of size 1
==3936==    at 0x4EB0ADD: _IO_default_xsputn (genops.c:481)
==3936==    by 0x4EAEBB2: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1364)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5206280 is 0 bytes inside a block of size 17 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 26 errors in context 5 of 12:
==3936== Invalid read of size 1
==3936==    at 0x4EC134B: __GI_mempcpy (memcpy.S:71)
==3936==    by 0x4EAEB11: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1329)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5206f50 is 0 bytes inside a block of size 18 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 32 errors in context 6 of 12:
==3936== Invalid read of size 4
==3936==    at 0x4EC136E: __GI_mempcpy (memcpy.S:95)
==3936==    by 0x4EAEB11: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1329)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5206db2 is 2 bytes inside a block of size 23 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 50 errors in context 7 of 12:
==3936== Invalid read of size 2
==3936==    at 0x4EC135B: __GI_mempcpy (memcpy.S:83)
==3936==    by 0x4EAEB11: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1329)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5205b70 is 0 bytes inside a block of size 19 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 61 errors in context 8 of 12:
==3936== Invalid read of size 8
==3936==    at 0x4EC137F: __GI_mempcpy (memcpy.S:107)
==3936==    by 0x4EAEB11: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1329)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x52073c5 is 5 bytes inside a block of size 14 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 75 errors in context 9 of 12:
==3936== Invalid read of size 1
==3936==    at 0x4EAEBDD: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1311)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5205b81 is 17 bytes inside a block of size 19 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 76 errors in context 10 of 12:
==3936== Invalid read of size 1
==3936==    at 0x4C2D7C2: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EA4ECB: puts (ioputs.c:36)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5206280 is 0 bytes inside a block of size 17 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 875 errors in context 11 of 12:
==3936== Invalid read of size 1
==3936==    at 0x4EAEBF9: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1311)
==3936==    by 0x4EA4F5F: puts (ioputs.c:41)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5205b80 is 16 bytes inside a block of size 19 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
==3936== 
==3936== 966 errors in context 12 of 12:
==3936== Invalid read of size 1
==3936==    at 0x4C2D7D4: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EA4ECB: puts (ioputs.c:36)
==3936==    by 0x400768: main (in /home/mazix/Desktop/tests/filenames)
==3936==  Address 0x5206281 is 1 bytes inside a block of size 17 free'd
==3936==    at 0x4C2BA6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3936==    by 0x4EF7DD3: globfree (glob.c:1278)
==3936==    by 0x400718: getFilenames (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936==    by 0x400737: main (in /home/mazix/Desktop/tests/filenames)
==3936== 
--3936-- 
--3936-- used_suppression:      2 dl-hack3-cond-1
==3936== 
==3936== ERROR SUMMARY: 2204 errors from 12 contexts (suppressed: 2 from 2)
4

1 回答 1

3

您没有复制文件名,而只是从数据中设置了指针。

filenames[i] = data.gl_pathv[i];

这是不正确的。您可以使用

filenames[i] = strdup(data.gl_pathv[i]);

您需要稍后在 main 中释放这个被复制的字符串,如下所示。

for(i=0; filenames[i] != NULL; i++)
{
    printf("%s\n", filenames[i]);
    free(filenames[i]);
}

这里指出了另一个问题。最后一个元素未设置为 NULL。

for(i=0; filenames[i] != NULL; i++)

分配一个额外的指针并将其设置为 NULL,如下所示。

filenames = malloc(sizeof(char*)*(data.gl_pathc+1));
for(i=0; i<data.gl_pathc; i++)
{
    filenames[i] = strdup(data.gl_pathv[i]);
}
filenames[i] = NULL;
于 2013-09-15T10:50:07.613 回答