【问题标题】:What is the difference between "hard-coding" and passing in arguments in regard to memory?“硬编码”和传入关于内存的参数有什么区别?
【发布时间】:2013-08-19 19:42:32
【问题描述】:

所以标题是我的问题。在内存中,参数可以位于堆栈或堆中,具体取决于它们的初始化方式,但如何处理硬编码信息?

例如,我将使用ifstream的构造函数

这有什么区别:

void function(){

    ifstream infile("home/some/file/path");

}

void function(char* filePath){

    ifstream infile(filePath); //filePath points to a character array which contains home/some/file/path

}

是否会因使用其中一个而产生任何记忆影响? (如果 char* 未正确释放,多线程可能会导致堆损坏?等等)。

我只是想了解差异和可能的含义,以便将答案应用于更大的问题。欢迎所有见解,如果我做出任何不正确的陈述/假设,请随时纠正我!

【问题讨论】:

  • 真的取决于filePath 是什么以及它是如何创建的。但是堆损坏不是由不是free'd 引起的。堆损坏是由于在其分配的缓冲区之外写入错误代码造成的。
  • 在您的第一个示例中,字符串将被放入进程的只读区域。所以那里没有什么可以造成损害的。
  • @MatsPetersson 如果你不介意我问,有多少种不同的方式来定义char*?我知道你可以做char* foo = (char*)malloc(16) 之类的事情,但还有什么其他的,比如流行的,有哪些方法,它会如何影响记忆?
  • 例如,您可以调用function("home/some/file/path") [虽然从技术上讲它应该是const - 但如果您直接将它传递给ifstream,这不是问题)。可能是char str[] = "some/file/path; function(str); ",也可能是main 中的function(argv[2])。这远不是一个完整的列表,但评论中只有这么多空间。 char * 可以通过多种方式出现在您的 function 中。
  • @bash.d 如果char 指针只指向一个字符数组并且从未“编辑”过,本质上只是用作文件路径,那么数据被指向的可能方式有哪些改变? (可能有些函数写的越界?)

标签: c++ heap-memory stack-memory hardcode


【解决方案1】:

文字(这是您的第一个示例显示的)被放入可执行文件的静态初始化部分(这就是为什么,如果您在 *Nix 系统上),您可以使用命令 strings 并获得一个列表应用程序中的所有文字。

您的第二个示例实际上应该修改为

void function(const char* filePath) { ... }

除非你要修改函数中的指针。该函数的内存可以来自任何地方(传递给函数的字符串文字,在应用程序的其他地方声明的常量字符串,存储在内存中并从命令行或控制台输入的字符串等)

您在使用多线程时会遇到的主要问题是,如果有 2 个以上的线程试图同时加载同一个文件。如果他们都在读取它可能不是问题,但是如果您有一个线程想要写入它并获得文件的排他锁,那么其他线程将死锁。不过,这与您的字符串问题没有直接关系。

【讨论】:

  • 谢谢,解释得很好。不过,我暂时不回答这个问题,因为我想进一步讨论它:)
【解决方案2】:

其他人已经很好地介绍了文字字符串存储在可执行文件的一些只读内存中,而指向 char 的指针只是直接指向该内存。

您的第二个选项是“好”、“坏”还是“以上都不是”在很大程度上取决于filePath 的来源。

显然,如果某些代码正在执行char *filename = new char [x]; strcpy(filename, "...");,则需要有一个对应的delete [] filename; - 并且x 需要足够长,以便字符串"..." 适合。

在这种情况下使用std::string 更安全,因为任何分配都由类处理,而解除分配则在析构函数中处理。

如果我们将线程放入等式中,我们还必须担心字符串的定义位置。在只有一个实例的类中,作为全局变量或在堆栈上。只有“堆栈”是安全的,并且有限制:如果您将指向 char * 的指针从 main [或创建线程之前的一些其他函数] 传递到线程中,您可以在内存中获得各种“乐趣”被多次分配到一个字符串中,数据被其他线程覆盖,你有什么。当然,如果线程没有更改数据,那么来自线程外部的全局变量或堆栈也没有问题。

这就是我所说的“这取决于字符串的创建方式”。细节绝对是最重要的。

【讨论】:

    【解决方案3】:

    “硬编码”或文字值通常是程序指令的一部分。例如,如果我做类似的事情

    int i = 0;
    

    值 0 是在架构级别使用汇编命令加载的。所以我的意思是它们由编译器和程序处理,可能根本不使用内存,或者在堆栈上。

    对于 char* 等值,首先我建议使用字符串,因为它们会相应地处理内存分配,但大字符串通常存储在堆上,而小字符串(小于 7 个字符左右)可以优化为在堆栈上处理(除非涉及“新”)。

    【讨论】:

      猜你喜欢
      • 2015-05-03
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 2010-10-01
      相关资源
      最近更新 更多