【问题标题】:passing local pointer to function FatFs将本地指针传递给函数 FatFs
【发布时间】:2017-04-06 17:57:04
【问题描述】:

我在 C 中有以下函数:

char* AUDIO_GetFile(FIL* fil, DIR* dir, FILINFO* fno) {
    FRESULT res;
    res = f_readdir(dir, fno); /* Read a directory item */
    if (fno->fname[0] == '\0')} /* End of files */
       ...
    }
    ...
    return &(fno->fname);
}

但是我需要一个临时变量来保留旧值,然后返回&(fno->fname)。我创建了局部变量FILINFO t_fno,然后将其传递给函数res = f_readdir(dir, &t_fno);,一切正常。

但是,如果我想使用 t_fno 作为本地指针,然后将其传递给 f_readdir,我不会得到实际数据,但会在 if (t_fno->fname[0] == '\0')} 上获得一些随机内存读数和程序崩溃。我也尝试过初始化FILINFO* t_fno = NULL,但这无济于事。

char* AUDIO_GetFile(FIL* fil, DIR* dir, FILINFO* fno) {
    FRESULT res;
    FILINFO* t_fno;
    res = f_readdir(dir, t_fno); /* Read a directory item */
    if (t_fno->fname[0] == '\0')} /* crash */
       ...
    }
    ...
    fno = t_fno;
    return &(fno->fname);
}


FRESULT f_readdir (
    DIR* dp,            /* Pointer to the open directory object */
    FILINFO* fno        /* Pointer to file information to return */
)
{
    FRESULT res;
    DEFINE_NAMEBUF;


    res = validate(dp);                     /* Check validity of the object */
    if (res == FR_OK) {
        if (!fno) {
            res = dir_sdi(dp, 0);           /* Rewind the directory object */
        } else {
            INIT_BUF(*dp);
            res = dir_read(dp, 0);          /* Read an item */
            if (res == FR_NO_FILE) {        /* Reached end of directory */
                dp->sect = 0;
                res = FR_OK;
            }
            if (res == FR_OK) {             /* A valid entry is found */
                get_fileinfo(dp, fno);      /* Get the object information */
                res = dir_next(dp, 0);      /* Increment index for next */
                if (res == FR_NO_FILE) {
                    dp->sect = 0;
                    res = FR_OK;
                }
            }
            FREE_BUF();
        }
    }

    LEAVE_FF(dp->fs, res);
}

【问题讨论】:

  • 我不确定您的问题是什么,但是; 'FILINFO* t_fno; res = f_readdir(dir, t_fno); /* 读取目录项 */' 将未初始化的指针传递给 f_readdir()。如果该指针被取消引用以进行读取或写入,则将导致UB,即。没用的:(
  • @ThingyWotsit Here is my problem。 UB是什么意思?指针未在 f_readdir 或任何需要 fno 的地方取消引用
  • UB == "未定义行为"

标签: c pointers fatfs


【解决方案1】:

根据its docsf_readdir() 期望它的第二个参数是“[p] 指向文件信息结构的指针,以存储有关读取项目的信息。”这与您描述的第一个用途一致,其中您将t_fno 声明为本地FILINFO 结构,并传递其地址。它与将 t_fno 声明为指针、使其未初始化并传递其不确定的初始值一致。

第二种方式会产生未定义的行为,这似乎非常合理,因为最慈善的解释是您已指示函数在某个随机位置写入数据。即使这样做成功,您也不知道会产生什么效果,或者当您稍后尝试读取它们时数据是否会保持不变,或者您是否可以稍后再读取它们。 C 不要求或为您提供任何推理 - 它只是声明行为未定义。你不能安全可靠地完成这项工作。

正如您所观察到的,初始化指针并没有帮助,除非(您没有探索)您将它初始化为指向与FILINFO 结构兼容的实际存储。指针声明本身只提供指针,而不提供任何指向的东西。示例:

char* AUDIO_GetFile(FIL* fil, DIR* dir, FILINFO* fno) {
    FRESULT res;
    FILINFO t_info;
    FILINFO* t_fno = &t_info;

    res = f_readdir(dir, t_fno); /* Read a directory item */

    // ...

在大多数情况下,我不希望单独维护t_fno,但保留它可能有可行的理由。

【讨论】:

  • 谢谢,有道理!
猜你喜欢
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多