C数组指针,转换和/或内存

1 c memory pointers casting

我不明白为什么这些指针值似乎是正确的,但我试图摆脱它们的值不是.(我很久以前就研究过C,而我最近还是试着回到它那里寻求乐趣).

这是我面临的问题的一个工作示例,但我不确定我做错了什么 - 我是否错误地投射指针,没有正确管理内存,或其他什么.

#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>

#define Q_STACK_MAX 100

typedef struct
{
    void* value[Q_STACK_MAX];
    int top;
} Stack;


void push(Stack* S, void* val)
{
    S->value[S->top] = val; 
    (S->top)++;
}

void* pop(Stack* S)
{
    (S->top)--;
    return (S->value[S->top]);
}

void init(Stack* S)
{
    S->top = 0;
}

int full(Stack* S)
{
    return (S->top >= Q_STACK_MAX);
}


void recursive_dir(char* dir, char* search, Stack* S)
{
    DIR* dp;
    struct dirent* entry;
    struct stat statbuf;
    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr, "error: %s\n", dir);
        return;
    }

    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        lstat(entry->d_name, &statbuf);

        if(S_ISDIR(statbuf.st_mode)) {
            if(strcmp(".", entry->d_name) == 0 ||
                strcmp("..", entry->d_name) == 0)
                    continue;

            recursive_dir(entry->d_name, search, S);
        } else {
            if( strstr(entry->d_name, search) != NULL ) {
                if(!full(S)) push(S, (void *)entry);

                printf("%p\n", entry);
                printf("%s [%x]\n", entry->d_name, entry->d_ino);
            } 
        }
    }
    chdir("..");
    closedir(dp);
}

int main() {
    Stack S;
    init(&S);
    int i;

    printf("\n");
    recursive_dir("/etc/", "conf", &S);
    printf("\n------------------------------\n");

    int top = S.top;
    struct dirent* entry;
    for (i=0; i<top; i++)
    {
        //struct dirent* entry = (struct dirent*)pop(&S);
        entry = (struct dirent*)S.value[i];

        printf("%p\n", entry);
        printf("%s [%x]\n", entry->d_name, entry->d_ino); 
    }

    printf("\n");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此输出的内容是dirent结构的指针值,该结构中的文件名以及文件序列号.然后它尝试将指向该指针的指针强制转换为(void*)并将其存储在临时堆栈中.

稍后,我尝试迭代堆栈中的值(以及数组),将其强制转换为dirent,然后显示相同的信息.

这有时会起作用,而在其他时候则不起作用.修剪后的输出示例:

...
0x7ff831806360
httpd-multilang-errordoc.conf [2cb6e07]
0x7ff831806398
httpd-ssl.conf [2cb6e08]
0x7ff8318063c0
httpd-userdir.conf [2cb6e09]
0x7ff8318063ec
httpd-vhosts.conf [2cb6e0a]
0x7ff831805250
httpd.conf [2cb6e0b]
0x7ff831805274
httpd.conf~previous [187a3]
0x7ff831807230
httpd-autoindex.conf [2cb6e10]
0x7ff831807260
httpd-dav.conf [2cb6e11]
0x7ff831807288
httpd-default.conf [2cb6e12]
0x7ff8318072b4
httpd-info.conf [2cb6e13]
...
--------------------------
...
0x7ff831807360
httpd-multilang-errordoc.conf [2cb6e17]
0x7ff831807398
httpd-ssl.conf [2cb6e18]
0x7ff8318073c0
httpd-userdir.conf [2cb6e19]
0x7ff8318073ec
httpd-vhosts.conf [2cb6e1a]
0x7ff831806250
 [0]
0x7ff831806230
320.whatis [2cb6ff6]
0x7ff8318042bc
asl.conf [2cb7d07]
0x7ff83180437c
autofs.conf [2cb6f5f]
0x7ff831805250
 [0]
0x7ff831805274
??$ [61666564]
0x7ff8318052e0
_response [6e7261]
...
Run Code Online (Sandbox Code Playgroud)

有时一切看起来都是正确的,有时文件句柄和/或名称完全被删除了.

一般来说,当我看到类似的东西时,因为我没有正确地处理内存 - 在垃圾收集世界中生活了这么长时间,我不会感到惊讶,但我不确定为什么或如何.

任何帮助,将不胜感激.

(我已经编了很多年了,我刚刚离开了C竞技场很长一段时间.请放轻松我.)

Bar*_*mar 5

dirent返回的结构readdir()可以在重复调用时重用内存.如果要保存它们,则应将它们复制到动态对象中,或先分配对象并调用readdir_r().