带指针的getcwd()返回“null”

时间:2016-05-21 12:48:07

标签: c arrays string pointers

我想回忆一下C编程。

我为自己找到的一项任务是使用指针在函数之间传递字符串变量。

所以 - 我想做什么:

  • 创建一个数组;
  • 创建一个指向此数组的指针;
  • 将指针作为参数传递给另一个函数;
  • 在第二个函数内调用#include <stdio.h> #include <unistd.h> int ch_str(char point1[]) { printf("Point 1: %s\n", point1); } int getpath (char point2[]) { printf("Path: %s\n", getcwd(point2, sizeof(point2))); } int main () { char str[20] = "this is string"; char *pStr; pStr = &str; ch_str(pStr); char pathname[1024]; char *pPathname; pPathname = &pathname; getpath(pPathname); printf("Direct: %s\n", getcwd(pathname, sizeof(pathname))); return 0; } ;
  • 打印结果。

这是我的代码:

ch_str()

getcwd()在这里 - 对我来说只是“测试”,以确保我做对了(他 - 他)指针。并且 - 这部分有效。

$ ./deploy Point 1: this is string Path: (null) Direct: /home/setevoy/ci 以指针作为参数 - 只需重新调整“null”:

getcwd()

我想 - 这里有一些(很大的......)误解了我身边的C指针,但是:

  

pathname[1024]函数将当前工作目录的绝对路径名复制到buf指向的数组

使用指针pPathname传递的数组(getcwd()),为什么pathname[1024]无法保存到<xsl:for-each select="//lbDMF/formularfields/formular[@tablename=$FKTable]"> <xsl:variable name="DisplayField1" select="@fkname"/> <xsl:variable name="FKFormularRefId" select="@formularid"/> <xsl:if test="//lbDMF/formulare/formular[@ID=$FKFormularRefId][@applicationid=$ApplicationID]/@applicationid=$ApplicationID"> Foo.VisibleIndex = <xsl:value-of select="position()-1"/>; 位置的路径?我在这里看不到什么?

4 个答案:

答案 0 :(得分:2)

在C中,作为函数参数的数组按引用传递,而不是按值传递。

这意味着在您的代码中,在函数getpath中,char point2[]的大小是char *的大小,而不是参数指向的数组的大小。

由于指针的大小太小而无法包含整个路径,因此会返回NULL。来自getcwd联机帮助页:

  

getcwd()函数将当前工作目录的绝对路径名复制到buf指向的数组,该数组是   长度尺寸。          如果当前工作目录的绝对路径名长度(包括终止空字节)超过size个字节,则返回NULL ,并将errno设置为ERANGE;应用程序应检查此错误,并在必要时分配更大的缓冲区。

答案 1 :(得分:2)

当您将数组作为参数传递时,函数将只获取指向第一个元素的指针。在此过程中,有关数组大小的信息将丢失。所以有你的问题。

getcwd(point2, sizeof(point2)));这个sizeof()是个问题。

在此处阅读更多内容:What is array decaying?

答案 2 :(得分:1)

引用getcwd联机帮助页:

  

返回值

 Upon successful completion, a pointer to the pathname is returned.  Oth-
 erwise a NULL pointer is returned and the global variable errno is set to
 indicate the error.  In addition, getwd() copies the error message asso-
 ciated with errno into the memory referenced by buf.

所以你可以打印errno(optionnaly,你可以使用strerror(3))来解决调用失败的原因。

您的代码基本上可以在我的计算机上运行,​​尽管我的编译器对您的演员阵容抱怨很多。

我不明白为什么要使用这个数组,该联机帮助页指出,如果你不提供缓冲区,它将被分配,你必须使用free(3)。所以基本上,你的代码可能就是:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>

char* getpath (void) {
  char *path = getwd(NULL);
  printf("Path: %s\n", path);
  return path;
}

int main () {
  char * dir = getpath();
  printf("I've got current path: %s\n", dir);
  free (dir);

  return 0;
}

答案 3 :(得分:0)

  

但是getcwd()用指针作为参数 - 只需重新调用&#34; null&#34;:

如果您使用以下getpath替换原始getpath2,您会看到预期的行为:

int getpath2 (char *point2) {
    printf("Path2: %s\n", getcwd(point2, 1024));
}

现在为什么这样做,原来的getpath没有?

首先检查getcwd的原型:

char *getcwd(char *buf, size_t size);

你看到它需要一个指针buf,而不是一个数组。你争辩说,等等,是不是数组参数衰减到指针?那是对的。但问题是你的sizeof,它现在是指针的大小,而不是数组,所以它(通常)是4。

但它仍然没有解释null输出?所以进行功能描述:

  

如果当前工作的绝对路径名的长度          目录,包括终止空字节,超过size字节,          返回NULL。

这里因为4没有足够的空间,所以你看到空输出。