2013-03-24 97 views
-1

溶液中发现奇怪的C++内存问题。常量指针被改变

问题描述: 我用一个旧的C库并具有这是接收一个const char *如在函数的自变量的类。该函数创建一个动态对象并使用const char *作为参数将其存储在链接列表中。

问题是,这样做后,传递给该函数的const char *在类外部的内存中被修改。这破坏了节点中的数据。

解决方案: 在类中使用std :: string作为数据类型。当const char *作为一个值传递给字符串时,字符串会为您处理内存管理。

我学到了什么? 使用C++时,总是使用字符串,如果需要在某个C库中使用,只能使用char *和string.c_str()。

谢谢你们。你救了我的周末。

+3

你能想出一个更小的例子,展示相同的问题?你链接的代码太大了,我们无法弄清楚它有什么问题...... – Xymostech 2013-03-24 17:24:17

+2

尝试使用valgrind。 – mfontanini 2013-03-24 17:25:44

+3

在SO,你的问题必须是独立的,而不是指一些外部网站。所以你真的需要修改你的代码并发布相关的代码片段,最好是一个合适的SSCCE(http://sscce.org)。 – hyde 2013-03-24 17:26:28

回答

1

buff在堆栈上创建。您将buff传递给Cache.find,最终它会成为您节点的关键。下一次你处理一个连接时,buff所占用的内存已被重用,因为你已经退出了声明buff的函数。所以你的密钥消失/被丢弃。基本上你有指向不再有效的内存的指针。

这正是你不应该尝试推出自己的原因,而是使用std :: map。

另外你似乎有多个线程修改全局变量,没有任何同步。

+0

我认为这是问题所在。我对C++编程非常陌生,基本上我不知道从哪里开始。如果我有一个const char *,我怎样才能将它复制到一个新的const char *中,以防止被篡改? – 2013-03-24 17:42:34

+0

不,你使用std :: string,那么你不必担心**。它会为你处理记忆。 – john 2013-03-24 17:43:16

+0

非常感谢。那是我的问题。我在处理C库时遇到了问题,因此我试图在程序中尽可能多地使用char *。将元素类型更改为std :: string,并简单地返回string.c_str()完全解决了问题。 – 2013-03-24 17:49:15

0

你可以更进一步煮沸。从浏览代码,这是我的猜测。从本质上讲,你在做什么错误是这样的:

const char* a; 
{ 
    std::string f("foo"); 
    a = f.c_str(); 
} 
doSomethingWith(a); 

我的建议是:从char*移动完全消失。如果有绝对必须使用它们的地方,请了解对象的生命周期以及如何让指针不以任何方式延长该生命周期。我不是说“不要使用char*,直到你更好地理解它们” - 我认为我理解它们很好,并且尽可能避免使用它们。我的意思是“如果你使用C代码(或者在这方面看起来像C代码的C++代码),使用它们”。

此外,上面的注释是绝对正确的。尽可能减少你的问题(这可能会给你答案),并以一种独立的方式在这里描述它。