在C中传递字符串最安全的方法是什么?

chu*_*son 5 c unix string pointers

我有一个使用Solaris的C程序,看起来很古老.许多例子,即使在这里,也不起作用,以及我在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;
}
Run Code Online (Sandbox Code Playgroud)

这似乎......马虎.任何人都能指出我在一个简单的要求上正确的方向吗?

更新

功能的一个例子,我对正在发生的事情感到茫然.不确定这是否足以解决这个问题,但这里有:'

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
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*yan 12

编写良好的C代码遵循以下约定:

  • 所有函数都返回int类型的状态代码,其中返回值0表示成功,-1表示失败.失败时,函数应设置errno适当的值(例如EINVAL).
  • 应通过使用"输出参数"报告函数"报告"的值.换句话说,其中一个参数应该是指向目标对象的指针.
  • 指针的所有权应该属于调用者; 因此,函数不应该free是它的任何参数,而应该只是free它本身分配的对象malloc/calloc.
  • 字符串应作为const char*对象或char*对象传递,具体取决于是否要覆盖该字符串.如果不修改字符串,const char*则应使用.
  • 每当传递的数组不是以NUL结尾的字符串时,应提供一个参数,指示数组中元素的数量或该数组的容量.
  • 当可修改的字符串/缓冲区(即char*)对象被传递到函数中,并且该函数将覆盖,追加或以其他方式修改字符串时,需要提供指示字符串/缓冲区容量的参数(以便允许用于动态缓冲区大小并避免缓冲区溢出).

我应该指出,在您的示例代码中,您将返回localstr而不是returnstr.因此,您将返回当前函数的堆栈帧中的对象的地址.函数返回后,当前函数的堆栈帧将消失.之后立即调用另一个函数可能会改变该位置的数据,从而导致您观察到的损坏.返回局部变量的地址会导致"未定义的行为"并且不正确.

编辑
根据您更新的代码(get_fullpath),很明显问题不在您的函数get_fullpath中,而是在调用它的函数中.最有可能的是,paths变量由返回局部变量地址的函数提供.因此,当您在get_fullpath中创建局部变量时,它在堆栈上使用与先前占用的路径相同的确切位置.由于"路径"是别名"fullpaths",它基本上是与你malloced缓冲区,这是空白的地址覆盖.

编辑2
我创建了一个C语言的表达约定页面上我的网站上有更具体的建议,解释和编写C代码的例子,如果你有兴趣.此外,自上次编辑问题以来,返回localstr而不是returntr的语句不再成立.