c++ - 在 C++ 中,Null 如何成为 "this"的可能值?

标签 c++ null

我对我的 native C++ 类之一中“this”的 NULL 值感到困惑。

我在 stdafx.h 中声明该类,如下所示:

extern Filing* Files;

然后在 stdafx.cpp 中实现它,如下所示:

Filing* Files = new Filing();

调试器会阻塞此方法,并抛出“写入访问冲突”: 消息还说:“这是 nullptr”。

void Filing::Startup()
{
this->ExePath = this->GetPathToExe(); //Throws right here
this->LogDirectoryPath = this->GetLogDirectoryPath();
CreateDirectory(LogDirectoryPath->c_str(), NULL);
}

这怎么可能?我该如何解决?完整的“归档”标题和定义如下。

归档.h:

#pragma once

#include <Windows.h>
#include <sstream>

using namespace std;

class Filing
{
  public:
     Filing();
     ~Filing();

/// <summary>
/// The path to this exe.
/// </summary>
     wstring* ExePath;

/// <summary>
/// The path to the log folder that exists or will be created.
/// </summary>
    wstring* LogDirectoryPath;

/// <summary>
/// Kicks off some startup logic.
/// </summary>
    void Startup();

/// <summary>
/// Determines if the specified directory exists.
/// </summary>
/// <param name="Path"></param>
/// <returns></returns>
    bool DoesDirectoryExist(string* Path);

  private:

/// <summary>
/// Returns the directory from which this executable is running from.
/// </summary>
    wstring* GetPathToExe();

/// <summary>
/// Gets the path to the log directory.
/// </summary>
/// <returns></returns>
    wstring* GetLogDirectoryPath();
};

归档.cpp:

#include "stdafx.h"
#include "Filing.h"

Filing::Filing()
{
   this->Startup();
}

Filing::~Filing()
{
   delete this->ExePath;
   delete this->LogDirectoryPath;
}

void Filing::Startup()
{
   this->ExePath = this->GetPathToExe();
   this->LogDirectoryPath = this->GetLogDirectoryPath();
   CreateDirectory(LogDirectoryPath->c_str(), NULL);
}

bool Filing::DoesDirectoryExist(string* Path)
{
   DWORD ftyp = GetFileAttributesA(Path->c_str());

   if (ftyp == INVALID_FILE_ATTRIBUTES)
   {
     Console->WriteLine("Invalid path!");
     return false;  //something is wrong with your path!
   }

   if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
   {
      return true;   // this is a directory!
   }

   return false;    // this is not a directory!
}

wstring* Filing::GetPathToExe()
{
   #ifdef UNICODE
   TCHAR ownPth[260];
   #else
   char ownPth[MAX_Path];
   #endif // UNICODE

   // Will contain exe path
   HMODULE hModule = GetModuleHandle(NULL);
   if (hModule != NULL)
   {
      // When passing NULL to GetModuleHandle, it returns handle of exe itself
      GetModuleFileName(hModule, ownPth, (sizeof(ownPth)));
      return new wstring(ownPth);
   }
   else
   {
      throw new exception("Error! NullPointerException!");
   }
}

wstring* Filing::GetLogDirectoryPath()
{
   //if (this == nullptr)
   //{
   //   int i = 0;
   //}

   wstring *directory;
   const size_t last_slash_idx = ExePath->rfind('\\');
   if (string::npos != last_slash_idx)
   {
      directory = new wstring(ExePath->substr(0, last_slash_idx));
      directory->append(L"\\Logs");
   }
   else
   {
      throw new exception("Error! Directory not found from path!");
   }
   return directory;
}

到目前为止我尝试过的事情:

清理并重建。

正在初始化归档。

编辑:

我看到一些关于不使用 stdafx.h 和 stdafx.cpp 来实现我正在使用的目的的评论。我现在将它们用于全局变量/类。我怎样才能在其他地方定义它们并且仍然是全局的?

编辑2:

将错误一直追溯到一个小 GetTime() 函数。

const char* Writer::GetTime()
{
    string* Formatted = new string("[");
    time_t rawtime;
    tm* timeinfo;
    char buffer[80];
    time(&rawtime);
    timeinfo = std::localtime(&rawtime);

    strftime(buffer, 80, "%Y-%m-%d-%H-%M-%S", timeinfo);
    Formatted->append(buffer);
    Formatted->append("]: ");

    const char* Ret = Formatted->c_str();

    delete Formatted;
    delete timeinfo;//Errors here SOMETIMES. Any ideas?
    return Ret;
}

最佳答案

下面是一个可能导致您看到this设置为NULL指针的程序示例。 (我说可能是因为根据C++语言规范,该程序会调用未定义的行为,因此从技术上讲,编译器可以自由地崩溃或为PacMan输出可执行文件或响应该源代码想做的任何其他事情代码...但在许多编译器实现中,常见的行为是 NULL this 指针。咳咳):

#include <stdio.h>

class Foo
{
public:
   Foo() {/* empty*/}

   void bar() {printf("this=%p\n", this);}
};

int main(int, char **)
{
   Foo * f = NULL;
   f->bar();  // undefined behavior here: calling a method on a NULL object!
   return 0;
}

当我运行该程序时,我得到以下输出:

$ ./a.out 
this=0x0

不用说,您不应该在任何实际程序中执行此操作。

对于您自己的代码,最可能的解释是您正在对 NULL 指针调用 Startup() 方法。解决方案是跟踪调用 Startup() 的所有位置,并在调用 Startup() 上的任何方法之前确保它们调用 Startup() 的指针为非 NULL(并指向有效对象)。

关于c++ - 在 C++ 中,Null 如何成为 "this"的可能值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45445863/

相关文章:

c++ - std::reference_wrapper<T> 的隐式 T& 构造函数是否会使使用变得危险?

c++ - NCURSES:创建没有循环的标题栏

c++ - 为什么在用户程序中动态分配缓冲区会导致内核驱动程序崩溃?

php - 如何使用 PHP/MySQLi 将 NULL 放入 MySQL 整数列中?

c++ - C++ 或 Qt 中的文件相关异常类

c++ - 为什么我随机生成的数字输入全零?

json - Golang/Go - 如果结构没有字段,如何将结构编码(marshal)为 null?

VHDL 中的 NULL 语句

c# - 返回为 null 的二维数组

java - 方法返回 null [简单]