1

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

例如,我将使用构造函数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* 未正确释放,多线程可能会导致堆损坏?等等)。

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

4

3 回答 3

2

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

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

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

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

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

于 2013-08-19T19:53:29.447 回答
1

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

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

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

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

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

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

于 2013-08-19T20:09:01.647 回答
0

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

int i = 0;

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

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

于 2013-08-19T19:47:56.657 回答