我有一个功能,可以将目录添加到已定义的路径中,或多或少地与命令提示符中的“ cd-function” 完全相同。第一次添加目录时,一切正常,第二次或第三次(取决于目录的长度),程序崩溃。
char path[PATH_MAX];
void dir_forward(char cmd[])
{
char *temp = malloc(strlen(path) + strlen(cmd) + 2);
char sep[] = "\\";
strcpy(temp, path); // copy path to temp
strcat(temp, sep);
strcat(temp, cmd+3); // +3 for removing "cd " from string
int i = strlen(temp); // add null terminator
temp[i] = '\0';
strcpy(path, temp);
free(temp);
printf("%s\n", path);
}
程序首先将路径复制到临时变量(临时变量的大小确定为路径,新目录,一个反斜杠和一个空终止符的大小)。之后,反斜杠和新目录将被复制到临时变量的路径中。空终止符将附加到字符串的末尾。然后,将临时变量中的新路径复制到该路径,从而替换旧路径。
让我通过一个例子进行演示,我有:
C:\ Users \ Paul \ Desktop \ some_folder
我决定将文件夹“ images”附加到路径:
C:\ Users \ Paul \ Desktop \ some_folder \ images
如果我再追加一个文件夹(最好使用长名称),程序将崩溃,就像缓冲区溢出一样,并且还会以一些奇怪的字符结束路径。
[编辑]
由于代码很大,我无法完全重现代码,但是,下面是该函数的本质。首先,程序在getcwd()的帮助下将路径添加到变量路径,然后接受输入并将其发送到上面的函数。
int main(void)
{
char cmd[30];
getcwd(path, PATH_MAX); // Get current path
scanf("%s", cmd);
dir_forward(cmd);
}
这应该足以重现我猜到的问题。
答案 0 :(得分:1)
不清楚为什么发布的代码失败,但是这里的规则#1是始终在复制之前检查数据的大小。另外,可以通过删除malloc简化整个功能。例如:
void dir_forward (const char cmd[])
{
cmd += sizeof("cd ") - 1; // remove "cd "
size_t dst_length = strlen(path);
size_t src_length = strlen(cmd);
size_t new_length = dstr_length + src_length + 2; // '\\' and '\0' give +2
if(new_length > PATH_MAX)
{
exit(EXIT_FAILURE);
}
char* ptr = &path[dst_length]; // point at null terminator
memcpy(ptr, cmd, src_length);
ptr += src_length;
*ptr = '\\';
ptr++;
*ptr = '\0';
}
完整示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef PATH_MAX
#define PATH_MAX 255
#endif
static char path[PATH_MAX] = "C:\\tmp\\";
void dir_forward (const char cmd[])
{
cmd += sizeof("cd ") - 1; // remove "cd "
size_t dst_length = strlen(path);
size_t src_length = strlen(cmd);
size_t new_length = dstr_length + src_length + 2; // '\\' and '\0' give +2
if(new_length > PATH_MAX)
{
exit(EXIT_FAILURE);
}
char* ptr = &path[dst_length]; // point at null terminator
memcpy(ptr, cmd, src_length);
ptr += src_length;
*ptr = '\\';
ptr++;
*ptr = '\0';
}
int main (void)
{
dir_forward("cd foo");
puts(path);
}
答案 1 :(得分:-1)
我找到了解决方案,将其发布以供将来参考。
问题出在这部分:
free(temp);
我不知道为什么(尽管这是必要的),但是我不得不删除它。
现在,至少一切正常。