为什么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);
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);