0

我发现了一些类似的代码(以下代码中有很多问题):

//setup consistent in each of the bad code examples
string someString; 
char* nullValue = getenv("NONEXISTENT"); // some non-existent environment variable  

// bad code example 1:
char x[1024];
sprintf(x," some text%s ", nullValue); //crashes on solaris, what about linux?  

// bad code example 2: 
someString += nullValue; // What happens here?  

//bad code example 3:
someString.append(nullValue); // What happens here?  

//bad code example 4:
string nextString=string(nullValue); //What happens here?
cout<<nextString;

我们正在使用 solaris、linux、gcc、sunstudio,将来很可能会使用 clang++。此代码的行为跨平台和编译器是否一致?在上述代码的所有情况下,我都找不到描述预期行为的规范。

目前,我们在使用 gcc(和在 linux 上)运行我们的代码时遇到问题,上面的代码可能是原因吗?

如果上面的代码在所有这些环境中的行为都相同,那么这对我来说是有价值的信息(即使行为是崩溃),因为我会知道这不是我们的 linux 问题的原因。

4

3 回答 3

2

一般来说,NULL 的这些使用(预期有效的 C 字符串)会导致未定义的行为,这意味着任何事情都可能发生。一些平台试图为此定义行为。IIRC 有一些平台可以优雅地处理将 NULL 指针传递给 printf 系列函数以进行 %s 格式替换(打印类似“(null)”的内容)。除此之外,一些平台试图确保此类情况下的可重现崩溃(例如致命信号)。但一般来说,你不能依赖这个。

如果您在代码的那个区域有问题:是的,这是一个可能的原因或可能掩盖其他原因,所以:修复它,它坏了!

于 2013-01-19T22:06:23.820 回答
1

从指针构造字符串时出现问题,而没有先检查返回值。getenv定义说:

检索包含名称被指定为参数的环境变量的值的 C 字符串。如果请求的变量不是环境列表的一部分,则该函数返回一个空指针。

C++ 标准std::string明确不允许从空指针创建a 。附加到字符串 ( +=) 也是如此。

我不是 C 专家,但有一种预感,sprintf也不允许使用空指针。

于 2013-01-19T22:00:55.663 回答
1

在您描述的任何情况下使用 NULL 指针时发生的确切情况是“未定义的行为”。一些 C 库确实可以识别 printf 中字符串的 NULL,并且会打印“(null)”或类似的内容,但我绝对不会依赖它。同样,您对 NULL 的其他用法是“未定义的”,这意味着它们保证不会在一系列平台上以任何特定方式工作。在一个平台上发生的事情很可能与在另一个平台上发生的事情完全不同(或者使用另一个品牌/版本的编译器,或者使用不同的编译器优化设置,或者如果你不走运,那一天的风向)。在这种情况下,它可能会导致崩溃或“行为良好的代码”——这取决于谁编写了 C/C++ 库。

One solution, if you have a few of these things is to create a "getenv_safe" that instead of returning NULL returns an empty string [or "not set" or similar] if the environment variable isn't set, and then either fix the code directly, or #define getenv(x) getenv_safe(x).

于 2013-01-19T22:36:18.463 回答