C语言中的动态大小字符串

C语言中的动态大小字符串,c,string,dynamic,realloc,strcat,C,String,Dynamic,Realloc,Strcat,我有下面的代码,可以编辑我将在我正在创建的程序中处理的“路径”字符串 我的问题是,我认为代码是有效的,但我不知道为什么或者更清楚地说,我不明白为什么strcat允许src附加到dest。既然一切都在使用动态字符串,我就不必realloc dest。但当我尝试时,realloc失败了 #include <stdio.h> #include <string.h> int main(int argc, char** argv) { char *src

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

我的问题是,我认为代码是有效的,但我不知道为什么或者更清楚地说,我不明白为什么
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;
    }
#包括
#包括
int main(int argc,字符**argv){
char*src=argv[1];
char*dest=argv[2];
char*d_basedir;
int s_length=strlen(src);
printf(“dest以%s开始:长度%zu\n”,dest,strlen(dest));
printf(“src从%s开始:长度%zd\n”,src,strlen(src));
如果(!(src[s_length-1]='/')){
if((d_basedir=strrchr(src,“/”)+1)!=NULL){
printf(“basedir是%s\n”,d_basedir);
strcat(目的地,d_basedir);
printf(“dest更改为%s:长度%zd\n”,dest,strlen(dest));
}
}
printf(“dest结束为%s:长度%zd\n”,dest,strlen(dest));
返回0;
}
实际上相当于:

strcat(argv[2], d_basedir);
这是一种未定义的行为。它可能今天起作用,明天失效。您有权向
argv[2][0]
写入到
argv[2][strlen(argv[2])]
但写入超过该元素(您使用
strcat
调用所做的操作)是未定义的行为

实际上相当于:

strcat(argv[2], d_basedir);

这是一种未定义的行为。它可能今天起作用,明天失效。您有权向
argv[2][0]
写入到
argv[2][strlen(argv[2])]
但写入元素(您使用
strcat
调用所做的)是未定义的行为。

它之所以有效,是因为您很幸运。就这些;-)

通过附加到dest,您将覆盖程序分配的一些内存,但它不会将其用于任何重要的事情。这就是为什么它“有效”

无法重新分配malloc未分配的内存。传递给main()的参数是内存的这些部分之一


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

它可以工作,因为您很幸运。就这些;-)

通过附加到dest,您将覆盖程序分配的一些内存,但它不会将其用于任何重要的事情。这就是为什么它“有效”

无法重新分配malloc未分配的内存。传递给main()的参数是内存的这些部分之一


您需要的是malloc足够大的新内存以容纳新路径,然后strcpy和strcat您需要的内存。

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

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

strcat
不关心
dest
。它只是一个指向char的指针,这就足够了

由于
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);

strcat
不关心
dest
。它只是一个指向char的指针,这就足够了

由于
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);

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

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

 char dest[PATH_MAX]; 

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

(这与您所写的略有不同,它将src path的d_basedir附加到dest的末尾,这在我看来是错误的)

我个人不会将realloc/malloc用于此类代码

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

 char dest[PATH_MAX]; 

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

(这与您所写的略有不同,它将src path的d_basedir附加到dest的末尾,这在我看来是错误的)

您不能
realloc()
malloc()
(或其近亲)获得的东西。您不能
realloc()
malloc()获得的东西(或其近亲)。修改
argv[2]
string的元素是完全定义的,但写入这些元素是未定义的。它已定义但并不理想,尤其是在这种情况下。第一个printf给出了argv[2]的长度这是dest的确切长度。那么这不意味着在结尾处有一个空字符,并且应该附加到它后面吗fail@johnsoga:您只能安全地假设
argv[2]
包含的字符数与
strlen()
所说的字符数相同,再加上一个(对于空字符)。这将根据从命令行调用程序的方式而改变,但不能假定程序末尾有更多空间来连接更多字符。如果需要更多空间,则需要自己创建(使用malloc或可变长度数组等)。