为什么指针在初始化后仍然是 nullptr
Why pointer remains nullptr after initialisation
我编写了二进制解析器来读取和打印有关文件的各种信息。出于速度原因,我希望直接使用 E32ImageHeader 数据而不是函数调用。
我传递了 nullptr 初始化变量,并且在函数 return 之后变量仍然是 nullptr。在 GetFileLayout() 中,gdb 为 iHdr 打印各种字段值,一些正确,其他需要修改。
代码看起来正确,但工具打印 "Header not recognized!!!",用于测试的二进制文件 kf__speedups_SDK.pyd 需要 here
main.cpp:
#include <iostream>
#include "e32info.h"
#include "e32parser.h"
using namespace std;
int main()
{
E32ImageHeader *hdr = nullptr;
E32Parser *parser = new E32Parser("AlternateReaderRecogE32.dll", hdr);
parser->GetFileLayout(hdr);
if(!hdr)
cout << "Header not recognized!!!\n";
// E32Info *f = new E32Info("h", "AlternateReaderRecogE32.dll");
// f->Run();
cout << "Hello world!" << endl;
delete parser;
return 0;
}
二进制解析器头文件e32parser.h:
#ifndef E32PRODUCER_H
#define E32PRODUCER_H
class E32ImageHeader;
class E32Parser
{
public:
E32Parser(const char* aFilename, E32ImageHeader *aHdr);
~E32Parser();
void GetFileLayout(E32ImageHeader *result);
private:
void ReadFile();
private:
E32ImageHeader *iHdr = nullptr;
const char *iFileName = nullptr;
char *iBufferedFile = nullptr;
size_t iE32Lenth = 0;
}
它是如何工作的
e32parser.cpp:
#include <fstream>
#include <cstring>
#include <cstdlib>
#include "e32common.h"
#include "e32parser.h"
E32Parser::E32Parser(const char* aFilename, E32ImageHeader *aHdr):
iHdr(aHdr), iFileName(aFilename)
{
}
E32Parser::~E32Parser()
{
delete iBufferedFile;
}
读取二进制文件到内部缓冲区
void E32Parser::ReadFile()
{
std::fstream fs(iFileName, fs.binary | fs.in);
if(!fs)
throw;
fs.seekg(0, fs.end);
int lenth = fs.tellg();
fs.seekg(0, fs.beg);
iBufferedFile = new char[lenth];
fs.read(iBufferedFile, lenth);
fs.close();;
}
void E32Parser::GetFileLayout(E32ImageHeader *result)
{
ReadFile();
iHdr = (E32ImageHeader*)iBufferedFile;
result = (E32ImageHeader*)iBufferedFile;
}
正如评论中指出的,您的问题是您正在修改传入的指针的副本。考虑这个小示例:
void modify(int* p) { p = new int{10}; }
int main()
{
int* n = nullptr;
modify(n);
if (n)
std::cout << *n;
}
这个程序的输出是空的(而且它泄漏了内存)。 modify
不会更改原始值,它会更改 n
的副本。解决此问题和您的程序的方法是通过引用传递指针。
void modify(int*& p) { p = new int{10}; }
和
void E32Parser::GetFileLayout(E32ImageHeader*& result)
但是,我认为更好的解决方法是 return 指针,以防止出现此问题:
E32ImageHeader* E32Parser::GetFileLayout()
{
...
iHdr = (E32ImageHeader*)iBufferedFile;
return iHdr;
}
但由于 iHdr
被传递给 E32Parser
,您可以将其更改为参考
我编写了二进制解析器来读取和打印有关文件的各种信息。出于速度原因,我希望直接使用 E32ImageHeader 数据而不是函数调用。
我传递了 nullptr 初始化变量,并且在函数 return 之后变量仍然是 nullptr。在 GetFileLayout() 中,gdb 为 iHdr 打印各种字段值,一些正确,其他需要修改。
代码看起来正确,但工具打印 "Header not recognized!!!",用于测试的二进制文件 kf__speedups_SDK.pyd 需要 here
main.cpp:
#include <iostream>
#include "e32info.h"
#include "e32parser.h"
using namespace std;
int main()
{
E32ImageHeader *hdr = nullptr;
E32Parser *parser = new E32Parser("AlternateReaderRecogE32.dll", hdr);
parser->GetFileLayout(hdr);
if(!hdr)
cout << "Header not recognized!!!\n";
// E32Info *f = new E32Info("h", "AlternateReaderRecogE32.dll");
// f->Run();
cout << "Hello world!" << endl;
delete parser;
return 0;
}
二进制解析器头文件e32parser.h:
#ifndef E32PRODUCER_H
#define E32PRODUCER_H
class E32ImageHeader;
class E32Parser
{
public:
E32Parser(const char* aFilename, E32ImageHeader *aHdr);
~E32Parser();
void GetFileLayout(E32ImageHeader *result);
private:
void ReadFile();
private:
E32ImageHeader *iHdr = nullptr;
const char *iFileName = nullptr;
char *iBufferedFile = nullptr;
size_t iE32Lenth = 0;
}
它是如何工作的 e32parser.cpp:
#include <fstream>
#include <cstring>
#include <cstdlib>
#include "e32common.h"
#include "e32parser.h"
E32Parser::E32Parser(const char* aFilename, E32ImageHeader *aHdr):
iHdr(aHdr), iFileName(aFilename)
{
}
E32Parser::~E32Parser()
{
delete iBufferedFile;
}
读取二进制文件到内部缓冲区
void E32Parser::ReadFile()
{
std::fstream fs(iFileName, fs.binary | fs.in);
if(!fs)
throw;
fs.seekg(0, fs.end);
int lenth = fs.tellg();
fs.seekg(0, fs.beg);
iBufferedFile = new char[lenth];
fs.read(iBufferedFile, lenth);
fs.close();;
}
void E32Parser::GetFileLayout(E32ImageHeader *result)
{
ReadFile();
iHdr = (E32ImageHeader*)iBufferedFile;
result = (E32ImageHeader*)iBufferedFile;
}
正如评论中指出的,您的问题是您正在修改传入的指针的副本。考虑这个小示例:
void modify(int* p) { p = new int{10}; }
int main()
{
int* n = nullptr;
modify(n);
if (n)
std::cout << *n;
}
这个程序的输出是空的(而且它泄漏了内存)。 modify
不会更改原始值,它会更改 n
的副本。解决此问题和您的程序的方法是通过引用传递指针。
void modify(int*& p) { p = new int{10}; }
和
void E32Parser::GetFileLayout(E32ImageHeader*& result)
但是,我认为更好的解决方法是 return 指针,以防止出现此问题:
E32ImageHeader* E32Parser::GetFileLayout()
{
...
iHdr = (E32ImageHeader*)iBufferedFile;
return iHdr;
}
但由于 iHdr
被传递给 E32Parser
,您可以将其更改为参考