将新路径追加到变量会使程序崩溃

时间:2018-11-14 06:56:41

标签: c

我有一个功能,可以将目录添加到已定义的路径中,或多或少地与命令提示符中的“ 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);
}

这应该足以重现我猜到的问题。

2 个答案:

答案 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);

我不知道为什么(尽管这是必要的),但是我不得不删除它。

现在,至少一切正常。