为什么strcat的结果是空的

Why is the result of strcat empty

char* path = malloc(128);
path = "/bin/"
char* path2 = malloc(128);
path2 = "ls"
strcat(path,path2);
fprintf(stderr, "%s\n",path);

结果为空。

但是如果我使用

char path[128] = "/bin/";
char* path2 = malloc(128);
path2 = "ls"
strcat(path,path2);
fprintf(stderr, "%s\n",path);

有什么区别 char path[128] 和 malloc?

在下面的代码中

char* path = malloc(128);
path = "/bin/";                   //added ;, you're overwriting the returned pointer
char* path2 = malloc(128);
path2 = "ls";                     // same as above
strcat(path,path2);               // the destination buffer is non-modifiable!!
fprintf(stderr, "%s\n",path);

你实质上是在覆盖分配器函数返回的内存(指针), 使这些指针指向字符串文字。因此, strcat() 调用调用未定义的行为,因为目标缓冲区是 non-modifiable (因为它们是字符串文字)。这会调用 undefined behaviour.

第二个片段问题较少

char path[128] = "/bin/";   // this is to be used as destination, OK
char* path2 = malloc(128);
path2 = "ls";               // you wouldn't need malloc here            
strcat(path,path2);
fprintf(stderr, "%s\n",path);

在这里,您正在分配一个足够大的数组(它是可修改的并且可以用作 strcat() 的合法目标缓冲区),所以从这方面来说您没问题。但是,对于第二个参数,您再次覆盖了 malloc() 返回的指针,导致内存泄漏。您不需要在此处使用 malloc(),只需将文字分配给指针并将其用作 strcat() 调用中的第二个参数。

char* 不像其他语言中的“字符串类型”那样工作。它是一个指针,所以当你写:

char* path = malloc(128);
path = "/bin/"

malloc 返回的内存已泄漏,因为您丢失了指向它的指针。

然后,当您尝试将内存连接到保存文字 "/bin/" 的内存中时,您会得到未定义的行为,因为您正在尝试修改支持字符串文字的内存。

让我为您注释这些...

第一个示例泄漏了 256 字节的内存并且可能会崩溃,具体取决于常量在内存中的驻留位置。

// Declare pointer path; malloc 128 bytes of heap memory and assign the address
char* path = malloc(128);
// Reassign the pointer (losing track of the malloc) to a string constant
// (could be in read-only memory if the compiler has deemed it wise)
path = "/bin/";
// Declare pointer path2; malloc 128 bytes of heap memory and assign the address
char* path2 = malloc(128);
// Reassign the pointer (losing track of the malloc) to a string constant
// (could be in read-only memory if the compiler has deemed it wise)
path2 = "ls";
// Attempt to concatenate strings; if `path` resides in read-only memory, this will segfault.
strcat(path, path2);
fprintf(stderr, "%s\n",path);

第二个示例泄漏了 128 字节的内存但不应崩溃(使用这些值;例如用户输入,您必须小心使用 strncat)。

// Declare pointer path to point to 128 bytes of stack memory (assuming in-function)
// and initialize it to "/bin/"
char path[128] = "/bin/";
// Declare pointer path2; malloc 128 bytes of heap memory and assign the address
char* path2 = malloc(128);
// Reassign the pointer (losing track of the malloc) to a string constant
// (could be in read-only memory if the compiler has deemed it wise)
path2 = "ls";
// Concatenate path2 to path in stack memory; this is fine (but could overflow)
strcat(path, path2);
fprintf(stderr, "%s\n",path);

正确的方法应该是这样的(如果你不打算 return path,那就是 stack-allocated)。不过,这并不能解决溢出问题。

// Declare pointer path to point to 128 bytes of stack memory (assuming in-function)
// and initialize it to "/bin/"
char path[128] = "/bin/";
// Concatenate the constant "ls" to path in stack memory (could still overflow)
strcat(path, "ls");
fprintf(stderr, "%s\n",path);