【发布时间】:2010-04-15 00:00:53
【问题描述】:
我有一个使用 Solaris 的 C 语言程序,它似乎具有非常古老的兼容性。很多例子,即使在 SO 上,也不起作用,还有我在 Mac OS X 上编写的很多代码。
那么当使用非常严格的 C 时,传递字符串最安全的方法是什么?
由于我认为简单,我目前在各处都使用 char 指针。所以我有返回 char* 的函数,我将 char* 传递给它们,等等。
我已经看到了奇怪的行为,比如当我输入一个函数时,我传递了一个 char*,它的值是正确的,然后在一个 printf() 或 malloc 之类的简单操作之后,该值神秘地消失或损坏/覆盖其他一些指针。
我确定是不正确的函数的一种方法可能是:
char *myfunction(char *somestr) {
char localstr[MAX_STRLENGTH] = strcpy(localstr, somestr);
free(somestr);
/* ... some work ... */
char *returnstr = strdup(localstr);
return returnstr;
}
这似乎……草率。任何人都可以在一个简单的要求上指出我正确的方向吗?
更新
我对正在发生的事情不知所措的一个函数示例。不确定这是否足以弄清楚,但这里是:'
char *get_fullpath(char *command, char *paths) {
printf("paths inside function %s\n", paths); // Prints value of paths just fine
char *fullpath = malloc(MAX_STRLENGTH*sizeof(char*));
printf("paths after malloc %s\n", paths); // paths is all of a sudden just blank
}
【问题讨论】:
-
我认为,更有可能的是,您正在做的事情会引发未定义的行为。在将其归咎于编译器或操作系统之前,我建议您与我们分享一些示例代码,以便我们可以告诉您碰巧在 OS X 上运行的原始代码是否真的有效。
-
这看起来……至少是错误的。您分配给数组 (???) ...您想将 strcpy 放入其中?你有一个 returnstr 但返回 localstr(在堆栈上,哎呀!)等等。无论如何,欢迎来到 C 的有趣世界。对象的所有权(是的,C 也有它们)必须明确定义。例如,如果上面的代码被调用为 myfunction("Hello world!") 会发生什么——无论如何,定义合约。一种方法是让 CALLER 负责传入一个能够接收 n 个字符的有效对象(如果需要更多,调用将失败,等等)
-
我对“真正严格的 C”的含义感到困惑。我同意迈克尔的观点,即您看到的“非常奇怪的行为”只是上面代码中未定义的行为。在 C 中没有特殊的方法来传递“字符串”,它与任何其他数组的工作方式相同。你到底有什么问题?
-
您是否要让函数返回原始字符串的副本?还是它的修改版?此外,如果您尝试为 MAX_STRLENGTH 个字符分配空间,则应该只有 sizeof(char),而不是 sizeof(char*)
-
当您调用 get_fullpath() 时,您不可能从之前调用 get_fullpath() 或类似构造函数中获得的指针传递参数 2,对吗?因为只要您回到较浅的堆栈深度,您可能会侥幸逃脱,只是当您再次深入调用树时才开始丢失缓冲区。