做PSET6,索引部分。得到它的工作,但是当我试图将结果从一个指针,从malloc移动到指针Char*[]
时,编译器抛出了一个拟合。
这是相关的一段代码
char *indexedPath = malloc(strlen(path) + strlen("/index.html") + 1);
DIR* dir;
struct dirent* sd;
dir = opendir(path);
if (dir == NULL)
{
printf("error\n");
return 1;
}
while( (sd = readdir(dir)) != NULL )
{
if (strcmp(sd->d_name, "index.html") == 0)
{
strcpy(indexedPath, path);
strcat(indexedPath, "index.html");
char* type[sizeof(indexedPath)+1];
strcpy(type, indexedPath);
free(indexedPath);
return type;
}
这是汇编的结果:
~/workspace $ make indexes3
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow indexes3.c -lcs50 -lm -o indexes3
indexes3.c:36:24: error: incompatible pointer types passing 'char *[8]' to parameter of type 'char *'
[-Werror,-Wincompatible-pointer-types]
strcpy(type, indexedPath);
^~~~
/usr/include/string.h:129:39: note: passing argument to parameter '__dest' here
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^
indexes3.c:38:21: error: incompatible pointer types returning 'char *[8]' from a function with result type
'char *' [-Werror,-Wincompatible-pointer-types]
return type;
^~~~
indexes3.c:38:21: error: address of stack memory associated with local variable 'type' returned
[-Werror,-Wreturn-stack-address]
return type;
我这几天都在摸不着头脑。我们必须释放函数中的内存,因为我们无法更改main。非常感谢。
答案 0 :(得分:1)
char* type[sizeof(indexedPath)+1];
strcpy(type, indexedPath);
free(indexedPath);
return type;
这是一个非常紧密的错误混合,一些编译错误和其他微妙的运行时错误伪装成"它有效!"因此,当您修复编译错误时,您一定会被误导。
首先让我们从那个微妙的误导性开始。您声明的数组(稍后返回指针的数组)将在函数返回时被销毁。重申一下,你要返回一个悬空指针(一个指向任何东西的指针)。
虽然这可能对您有用(一旦您修复了编译错误),但它无法保证,便携或以任何方式可靠。您可能会注意到它会在短时间内停止工作。
一种解决方案是返回indexedPath
(而不是free
在这里);当函数返回时,它不会被销毁。不幸的是,调用者必须free
那块内存。
更好的是,您可以更改函数以接受一个参数,该参数告诉您存储字符串的位置(例如fgets
样式)。
这也可能解决编译问题,但仅仅是因为你不需要indexedPath
或任何基于它的逻辑,这就是导致编译的原因错误。让我们再讨论一下。
以下是char *
变量的样子:
char *foo;
以下是您的变量的样子:
char *foo[bar];
你看到不一致吗?您的编译器告诉您strcpy
的第一个参数需要是char *
。您还可以提供char[bar]
数组,该数组将隐式转换为char *
。这样的数组将被声明为:
char foo[bar];
然而,正如我们之前讨论的那样,当你的函数返回时,它会被破坏,这意味着你将返回一个悬空指针。不是一个很好的解决方案,嗯?