我的处境真的很奇怪。我正在制作一个linux多线程c应用程序,它使用了所有涉及char*字符串的基本内存,我陷入了一个非常奇怪的境地。
基本上,所发生的是,使用posix线程,我正在读写一个二维char数组,但它有不寻常的错误。我保证,我已经对它们各自访问的内容进行了大量测试,它们不会读取其他线程的数据,更不用说向其他线程写入数据了。当处理数组的最后一个线程改变了它在数组中的部分时,它似乎改变了数组中的最后几个字符,并将字符放在其中,我不知道它们可能是如何进入的;主要是打印为黑钻石问号的字符。
我用的是valgrind和gdb,它们并没有真正的帮助。据我所知,一切都应该有效。瓦尔格林告诉我,我不是什么都能自由。
我知道所有这些听起来都很不规范,但这里有个奇怪的地方:如果我用电子围栏编译我的程序,那么它就都能工作了。valgrind告诉我,我正在释放所有的东西,没有任何记忆错误,就像我想的那样。它的工作绝对完美!
所以,我想我的问题是,为什么我的程序在用电围栏编译时运行良好?
(同时作为一个附带问题,需要采取哪些步骤来确保100%的“线程安全”代码?)

最佳答案

我听说,电动围栏为你的每一次分配至少两页纸。它使用oss分页机制来检查分配之外的访问。这意味着如果你想要一个新的14个字符的数组,你最终会得到一个全新的页面来保存它,比如8K。大部分页面都没有使用,但是你可以通过观察哪些页面被使用来检测错误的访问。我可以想象,由于有这么多额外的空间,如果一个问题过去的警卫,你不会看到一个错误。
如果您没有坏的访问,而是由于两个线程没有正确锁定而导致的损坏,efence将不会检测到它。efence还可能保留指向已分配内存的指针,欺骗valgrind报告没有问题。您应该使用--show-reachable=yes标志运行valgrind,并在运行结束时查看无人认领的内容。

关于c - 奇怪的C程序行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3535537/

10-13 03:58