-3

在 C++ 中,我在 char 指针的帮助下写入内存区域。我的 char 指针如下:

  unsigned char * writer;
  *(writer++)=0xF1; //example of write

现在我的问题是,一旦我写......我的程序中的其他一些写能够覆盖这些数据......由于我在阅读时得到不正确的结果。因为我只写了一次..在 C/C++ 中有什么方法可以让我能够保持这个内存区域不变(不变)..这样程序的其他部分就不会覆盖它。

4

4 回答 4

4

不便携,不。

您也许可以使用操作系统提供的工具将整个内存页面标记为只读。这可能对您有用,也可能对您不起作用,具体取决于您是否可以将相关字节隔离到专用内存页面中。这也有点像大锤的方法。

如果您想这样做以解决错误,那么更好的方法是找到并修复错误。例如,如果您怀疑存在内存损坏,valgrind这是一个非常有用的工具。

于 2013-03-27T14:18:16.207 回答
1

您没有提供足够详细的解释来给出确切的答案,但我原以为只需传递指针const就足以完成您想要的操作:

const unsigned char *writer;

也许将写入功能包装到一个类中,并且只允许const访问内存:

class MemWriter
{
private:
    unsigned char *writer;
public:
    const unsigned char *getMemory() const
    {
        return writer;
    }
    //
    // Other methods to perform the writing defined here
    //
};

这实际上不会阻止代码将指针转换为 non-const并写入它,但它至少会表明您的意图是内存是只读的。

于 2013-03-27T14:18:33.897 回答
0

在 C++ 中,没有什么可以阻止您写入程序可用的地址空间,只要您有它的地址 - 32 位/64 位整数。使用 const 之类的关键字来防止意外覆盖,并使读者清楚您的意图。在下面的代码中,让我们看看我们如何处理地址号,假设是一台 32 位机器。

int main()
{
    int i = 998979789;

    std::cout << i << std::endl;

    int j = (int)(&i);// get the address number

    char * m = (char*)j; // change to a char*

    char old = m[0]; // store the  char for later use

    m [0] = 'A'; // write over the memory

    std::cout << i << std::endl;

    m[0] = old; // again write to bring it back

    std::cout << i << std::endl;

    return 0;
}
于 2013-03-27T14:58:42.540 回答
0

如果您试图保护您可以信任的例程不会将指向 const 的指针转换为指向非 const 的指针,但可能会无意中写入应视为常量的缓冲区(例如,由于印刷错误或由于编写例程时的粗心大意),然后只需将指针转换为指向 const 的指针,然后仅将其传递给其他例程。当例程尝试通过指向常量的指针进行写入时,编译器通常会发出警告或错误。(其中有一些漏洞,例如strchr例程。)当您稍后释放内存时,您可能需要记录指向非常量的原始指针,或者您将不得不“强制”转换指针 - to-const 返回指向非 const 的指针。

如果您试图防止例程可能溢出缓冲区或以其他方式严重误入歧途的错误,请检查您的计算平台是否提供mprotect调用。这将需要在页面对齐的地址处以页面大小为单位分配内存(您的平台可能有这样的调用valloc)。同样,当需要释放内存时,您可能需要更改保护以允许再次写入。

于 2013-03-27T14:26:52.293 回答