从结构指针内部打印字符串时输出错误 (VC++ 2010)

Wrong output when printing a string from inside a struct pointer (VC++ 2010)

我发现 printf(和 printf_s)和 std::cout 都有一个非常奇怪的问题。我不确定它是否缺少 "glitch" 或这些函数中的错误,或者我是否做错了什么。由于这两个函数的作用相同,我假设我没有以正确的方式进行操作。

我的程序中有以下结构(顺便说一句,这是一个Visual C++ 2010项目):

#pragma pack(push, 1)
typedef struct nameentry
{
    char NAME[17];
    char EXT[4];
}NAMEENTRY;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct fileentry
{
    unsigned int ID;
    NAMEENTRY FILENAME;
    unsigned int GPFID;
    unsigned long long int FPOINTER;
    size_t FILESIZE;
}FILEENTRY;
#pragma pack(pop)

现在我有以下部分代码:

NAMEENTRY fname = MCreateNameEntry("LONGFILE.JPG");
FILEENTRY* myfile_ = SearchFileByPkgID(0, fname);
printf("%s", myfile_->FILENAME.NAME);

所以这段代码应该做的是,创建一个 NAMEENTRY 的实例,其中 NAME=LONGFILE,EXT=JPG。两个字符数组都以 null 结尾(最后一个字节是 0)。然后使用我正在开发的数据库中的相应数据创建一个 FILEENTRY 实例,然后从 FILEENTRY 的 NAMEENTRY 结构中打印文件名。

在 运行 代码之后,我得到的不是文件名,而是...垃圾。尝试从坏指针打印文本时得到的经典垃圾。如果我尝试打印任何其他字段,我也会得到错误的值。

很明显,我的第一个想法是我的一个函数没有返回正确的值。所以我开始检查代码,令我惊讶的是,它们实际上返回了正确的值,并且结构中填充了正确的数据。我在每个字段中都得到了正确的值,每个字符数组都以 0 结尾,等等

然后我说..."What if I copy the entire block into another instance of FILEENTRY?",然后我尝试了这个:

NAMEENTRY fname = MCreateNameEntry("LONGFILE.JPG");
FILEENTRY* myfile_ = SearchFileByPkgID(0, fname);
FILEENTRY dMem;

memcpy(&dMem, myfile_, sizeof(FILEENTRY));

printf("%s", dMem.FILENAME.NAME);

你猜怎么着?它工作得很好。我得到文件的名称,没有垃圾。所以我假设,问题出在 printf 内部(我也尝试 std::cout 得到相同的结果),或者我在使用这些函数时做错了。

嗯,这很有帮助。正如 Igor Tandetnik 所建议的,问题似乎是 return 指向局部变量的指针。

因此,作为一种解决方法,我不确定这是否是处理此问题的正确方法,我没有定义局部变量,而是使用 calloc 为 FILEENTRY 指针分配内存块,然后填充它和 return 它。是的,它似乎是这样工作的。

这是函数的实际代码:

FILEENTRY* SearchFileByPkgID(int ID, NAMEENTRY fname)
{
    FILEENTRY* myFile = (FILEENTRY*)calloc(sizeof(FILEENTRY),1);
    std::vector<int> results;
    unsigned int* dptable = GetDPTableByPkgId(ID);
    bool found = false;

    for(int x = 0; x < 1024; x++)
    {
        if(dptable[x] > 0)
        {
            fseek(PDBFILE, dptable[x], SEEK_SET);
            fread(myFile, sizeof(FILEENTRY), 1, PDBFILE);
            if(strcmp(myFile->FILENAME.EXT, fname.EXT) == 0)
                if(myFile->FILENAME.NAME[0] == fname.NAME[0])
                    results.push_back(dptable[x]);
        }
    }


    for(int y = 0; y < results.size(); y++)
    {
        fseek(PDBFILE, results[y], SEEK_SET);
        fread(myFile, sizeof(FILEENTRY), 1, PDBFILE);
        if(strcmp(myFile->FILENAME.NAME, fname.NAME) == 0)
        {
            found = true;
            break;
        }
    }

    results.clear();

    if(found)
        return myFile;
    else
        return 0L;
}

欢迎大家多提建议