我完成了所有功能的实现,但是我的代码未通过第二次检查。我不确定问题的确切位置,但它可能在我的加载或索引函数中,因为我的代码成功完成了第一次检查。有人可以帮我搞清楚吗?哦,由于某种原因,我的GDB无法正常工作。提前致谢!
这是我的代码:
char *indexes(const char *path) {
char *copy = malloc(strlen(path));
strcpy(copy, path);
char *php = "/index.php\0";
char *html = "/index.html\0";
char *check_php = malloc(strlen(copy) + strlen(php));
char *check_html = malloc(strlen(copy) + strlen(html));
check_php = strcat(copy, php);
check_html = strcat(copy, html);
if (access(check_php, F_OK) == 0)
return check_php;
else
if (access(check_html, F_OK) == 0)
return check_html;
return NULL;
}
bool load(FILE *file, BYTE **content, size_t *length) {
char *store = malloc(5000);
int count = 0;
char c;
do {
c = fgetc(file);
if (feof(file))
break;
else
if (count % 5000 == 0)
store = realloc(store, count + 5000);
store[count] = c;
count++;
} while (true);
*content = &store[0];
*length = count;
return true;
}
答案 0 :(得分:3)
您的代码中存在许多问题:
函数indexes()
中存在一个经典错误:
char *copy = malloc(strlen(path));
strcpy(copy, path);
您必须为空终止符分配一个字节:
char *copy = malloc(strlen(path) + 1);
strcpy(copy, path);
或者您可以在系统上使用Posix函数strdup()
:
char *copy = strdup(path);
连接尝试的类似问题:
char *check_php = malloc(strlen(copy) + strlen(php));
char *check_html = malloc(strlen(copy) + strlen(html));
check_php = strcat(copy, php);
check_html = strcat(copy, html);
您没有分配足够的内存, plus 您没有将字符串复制到已分配的内存中,而是连接到已经填满的copy
的末尾。你应该写:
char *check_php = malloc(strlen(copy) + strlen(php) + 1);
char *check_html = malloc(strlen(copy) + strlen(html) + 1);
strcpy(check_php, copy);
strcpy(check_php, php);
strcpy(check_html, copy);
strcpy(check_html, html);
在离开此功能之前,您没有free
不再使用的字符串。这很草率,导致内存泄漏。
功能load()
中存在更多不太紧急的问题:
fgetc()
的返回值应存储在int
中。检查文件末尾的方式虽然不是技术上的错误,但是容易出错并且不推荐,你应该写下这个:
int c = fgetc(fp);
if (c == EOF)
break;
重新分配方案是多余的:如果count == 0
您调用的realloc()
与初始malloc()
调用的大小相同。您只需将store
初始化为NULL
,并仅依靠realloc
进行分配。如果该文件为空,则*length
将设置为0
而*bytes
设置为NULL
,这应该没问题。
另一种方法是在将指针存储到store
之前将*bytes
重新分配给读取的实际大小。
do { ... } while (true);
不是读者友好的:使用for (;;) { ... }
立即告诉读者这个无限循环的性质会好得多。
答案 1 :(得分:2)
代码中有很多错误。我创建了两个版本。一个带有注释和纠正的错误。另一个清理并简化了。
以下是带#if 0 /*original code*/ #else /*fixed code*/ #endif
的注释版本:
char *
indexes(const char *path)
{
// NOTE/BUG: malloc for string must allow for EOS char
#if 0
char *copy = malloc(strlen(path));
#else
char *copy = malloc(strlen(path) + 1);
#endif
// NOTE/BUG: no need to duplicate path -- it can be used directly
strcpy(copy, path);
// NOTE/BUG: the \0 is redundant
#if 0
char *php = "/index.php\0";
char *html = "/index.html\0";
#else
char *php = "/index.php";
char *html = "/index.html";
#endif
// NOTE/BUG: malloc for string must allow for EOS char
#if 0
char *check_php = malloc(strlen(copy) + strlen(php));
char *check_html = malloc(strlen(copy) + strlen(html));
#else
char *check_php = malloc(strlen(copy) + strlen(php) + 1);
char *check_html = malloc(strlen(copy) + strlen(html) + 1);
#endif
// NOTE/BUG: copy doesn't have enough space to hold the concat and is wrong
// NOTE/BUG: this is trashing the above values and, thus, leaking memory
#if 0
check_php = strcat(copy, php);
check_html = strcat(copy, html);
#else
strcpy(check_php,copy);
strcat(check_php,php);
strcpy(check_html,copy);
strcat(check_html,html);
#endif
// NOTE/BUG: this is leaking memory of the unused check_html
#if 0
if (access(check_php, F_OK) == 0)
return check_php;
#else
if (access(check_php, F_OK) == 0) {
free(check_html);
return check_php;
}
#endif
// NOTE/BUG: this is leaking memory of the unused check_php
#if 0
if (access(check_html, F_OK) == 0)
return check_html;
#else
if (access(check_html, F_OK) == 0) {
free(check_php);
return check_html;
}
#endif
// NOTE/BUG: this is leaking memory of the unused check_php and check_html
#if 1
free(check_html);
free(check_php);
#endif
return NULL;
}
以下是已清理的版本:
char *
indexes(const char *path)
{
char *php = "/index.php";
char *html = "/index.html";
size_t plen = strlen(path);
char *file;
file = malloc(plen + strlen(php) + 1);
strcpy(file,path);
strcat(file,php);
if (access(file, F_OK) == 0)
return file;
free(file);
file = malloc(plen + strlen(html) + 1);
strcpy(file,path);
strcat(file,html);
if (access(file, F_OK) == 0)
return file;
free(file);
return NULL;
}
答案 2 :(得分:1)