1

我有以下代码并编辑我将在我正在创建的程序中处理的“路径”的字符串。

我的问题是我的代码有效,但我不知道为什么或更清楚我不明白为什么strcat允许src附加到dest. 由于一切都在使用动态字符串,我不应该这样做realloc dest。但是当我尝试时,realloc失败了

#include <stdio.h>
#include <string.h>

    int main(int argc, char** argv) {
        char *src = argv[1];
        char *dest = argv[2];
        char *d_basedir;
        int s_length = strlen(src);

        printf("dest starts as %s: length %zu\n", dest, strlen(dest));
        printf("src starts as %s: length %zd\n", src, strlen(src));

        if(!(src[s_length - 1] == '/')) {
            if((d_basedir = strrchr(src, '/')+1) != NULL) {
                printf("basedir is %s\n", d_basedir);
                strcat(dest, d_basedir);
                printf("dest changed to %s: length %zd\n", dest, strlen(dest));
            }
        }

        printf("dest ends as %s: length %zd\n", dest, strlen(dest));

        return 0;
    }
4

5 回答 5

1

托管环境为您提供了argv[]数组,但您没有分配此内存,因此您不应尝试重新分配它。你根本不应该真正修改argv[]。如果要进行修改,请先复制字符串(使用malloc等),然后至少可以确定是否有足够的空间,或者realloc在连接之前是否需要使用。

于 2013-01-29T23:15:15.583 回答
0
strcat(dest, d_basedir);

实际上相当于:

strcat(argv[2], d_basedir);

这是未定义的行为。它可能今天有效,明天失败。您有权写入argv[2][0]up toargv[2][strlen(argv[2])]但超过该元素(您对strcat呼叫所做的事情)是未定义的行为。

于 2013-01-29T23:14:01.807 回答
0

它有效,因为你很幸运。就这样 ;-)

通过附加到 dest,您将覆盖程序已分配的一些内存,但它不会将其用于任何重要的事情。所以这就是它“起作用”的原因。

您不能重新分配不是由 malloc 分配的内存。传递给 main() 的参数是这些内存部分之一。

您想要的是为新路径分配足够大的新内存,然后将 strcpy 和 strcat 放入其中。

于 2013-01-29T23:15:07.577 回答
0

strcat不在乎dest。它只是一个指向 char 的指针,对于strcat来说已经足够了。

由于argv[2]来自环境,因此不允许添加到 dest (argv[2])。正确的方法是分配足够的内存,复制argv[2]到它并附d_basedir加到它

char *dest = malloc(strlen(argv[2]) + strlen(d_basedir) + 1);
strcpy(dest, argv[2]);
strcat(dest, d_basedir);
于 2013-01-29T23:16:47.977 回答
0

我个人不会对这类代码使用 realloc/malloc。

您可以使用 PATH_MAX(或在某些情况下为 MAX_PATH)来确定您需要的最长路径。

 char dest[PATH_MAX]; 

 strcpy(dest, d_basedir);
 strcat(dest, argv[2]); 

(这与您编写的内容略有不同,它将 src-path 的 d_basedir 附加到 dest 的末尾,这对我来说似乎是错误的)

于 2013-01-30T00:08:18.837 回答