为什么这个简单的 C 程序会在运行时崩溃?
Why does this simple C program crash at runtime?
我尝试了以下简单的 C 程序,但它在运行时崩溃,没有给出任何输出。这里有什么问题?我该如何解决这个问题?
#include <stdio.h>
#include <string.h>
int main(void)
{
char *s1="segmentation";
char *s2="fault";
char *s3=strcat(s1,s2);
printf("concatanated string is %s",s3);
}
所以这是这个问题的综合答案:
您不应该尝试以任何方式改变字符串文字。根据 C 标准,更改字符串文字会导致 未定义的行为:
"It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined."
但假设 s1 不是字符串文字的讨论 - 您仍然需要有足够的缓冲区供 strcat 处理 - strcat 找到 nul 终止字符并开始在其上写入您要附加的字符串。如果您的缓冲区不够大 - 您将尝试在数组的边界之外写入 - 再次导致未定义的行为。
因为 strcat 在他的第一个参数上追加函数。
即结果将存储在 s1 而不是 s3
您应该为 s1 分配更多内存。
即:
char* s1 = malloc(sizeof(char) * (13 + 6)); //length of your 2 strings
strcpy(s1, "segmentation");
char *s2="fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);
这里最有问题的是你将 s1
和 s2
声明为 char *
而不是 const char*
- 在这种情况下总是使用 const
- 当您以这种方式初始化字符串时,这是 只读 内存。
如果你想扩展s1中的字符串,你不应该像你那样初始化它,而是应该在堆栈或动态内存中为s1
分配内存。
在堆栈上分配的示例:
char s1[100] = "segmentation";
动态内存分配示例:
char *s1 = malloc(100 * sizeof(char));
strcpy(s1, "segmentation");
我在这里使用 100 因为我认为这对您的字符串来说已经足够了。您应该始终分配一个数字,该数字至少是字符串的长度 + 1
看strcat()
的定义
char *strcat(char *dest, const char *src)
dest -- This is pointer to the destination array, which should contain a C string, and should be large enough to contain the concatenated resulting string.
src -- This is the string to be appended. This should not overlap the destination.
s1
不足以 容纳连接的字符串,这会导致写入超出限制。它会导致 运行 次失败。
试试这个,
char *s1="segmentation";
char *s2="fault";
char* s3 = malloc(sizeof(s1) + sizeof(s2));
strcpy(s3, s1);
strcat(s3, s2);
在 comp.lang.c 上找到了一个类似的,它也有深入的回答。
the main problem here is that space for the concatenated result is not
properly allocated. C does not provide an automatically-managed string
type. C compilers allocate memory only for objects explicitly
mentioned in the source code (in the case of strings, this includes
character arrays and string literals). The programmer must arrange for
sufficient space for the results of run-time operations such as string
concatenation, typically by declaring arrays, or by calling malloc.
strcat() performs no allocation; the second string is appended to the
first one, in place. The first (destination) string must be writable
and have enough room for the concatenated result. Therefore, one fix
would be to declare the first string as an array:
The original call to strcat in the question actually has two problems:
the string literal pointed to by s1, besides not being big enough for
any concatenated text, is not necessarily writable at all.
其他人关注的是 s1
中的 space 不足以进行字符串连接。但是,这里更大的问题是您正在尝试修改 字符串文字 ,这是未定义的行为。将 s1
定义为具有足够 space 的字符数组应该可行:
char s1[20] = "segmentation";
char *s2 = "fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);
char *s1="segmentation";
s1
是一个不可变的字符串,它将驻留在read-only
内存中。如果您查看 strcat
定义:
char *strcat(char *dest, const char *src)
here
dest
-- 这是指向目标数组的指针,它应该包含一个 C 字符串,并且应该足够大以包含连接的结果字符串。
所以当您调用 char *s3=strcat(s1,s2);
时,您试图修改导致分段错误的不可变字符串。
我尝试了以下简单的 C 程序,但它在运行时崩溃,没有给出任何输出。这里有什么问题?我该如何解决这个问题?
#include <stdio.h>
#include <string.h>
int main(void)
{
char *s1="segmentation";
char *s2="fault";
char *s3=strcat(s1,s2);
printf("concatanated string is %s",s3);
}
所以这是这个问题的综合答案:
您不应该尝试以任何方式改变字符串文字。根据 C 标准,更改字符串文字会导致 未定义的行为:
"It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined."
但假设 s1 不是字符串文字的讨论 - 您仍然需要有足够的缓冲区供 strcat 处理 - strcat 找到 nul 终止字符并开始在其上写入您要附加的字符串。如果您的缓冲区不够大 - 您将尝试在数组的边界之外写入 - 再次导致未定义的行为。
因为 strcat 在他的第一个参数上追加函数。 即结果将存储在 s1 而不是 s3
您应该为 s1 分配更多内存。 即:
char* s1 = malloc(sizeof(char) * (13 + 6)); //length of your 2 strings
strcpy(s1, "segmentation");
char *s2="fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);
这里最有问题的是你将 s1
和 s2
声明为 char *
而不是 const char*
- 在这种情况下总是使用 const
- 当您以这种方式初始化字符串时,这是 只读 内存。
如果你想扩展s1中的字符串,你不应该像你那样初始化它,而是应该在堆栈或动态内存中为s1
分配内存。
在堆栈上分配的示例:
char s1[100] = "segmentation";
动态内存分配示例:
char *s1 = malloc(100 * sizeof(char));
strcpy(s1, "segmentation");
我在这里使用 100 因为我认为这对您的字符串来说已经足够了。您应该始终分配一个数字,该数字至少是字符串的长度 + 1
看strcat()
char *strcat(char *dest, const char *src)
dest -- This is pointer to the destination array, which should contain a C string, and should be large enough to contain the concatenated resulting string.
src -- This is the string to be appended. This should not overlap the destination.
s1
不足以 容纳连接的字符串,这会导致写入超出限制。它会导致 运行 次失败。
试试这个,
char *s1="segmentation";
char *s2="fault";
char* s3 = malloc(sizeof(s1) + sizeof(s2));
strcpy(s3, s1);
strcat(s3, s2);
在 comp.lang.c 上找到了一个类似的,它也有深入的回答。
the main problem here is that space for the concatenated result is not properly allocated. C does not provide an automatically-managed string type. C compilers allocate memory only for objects explicitly mentioned in the source code (in the case of strings, this includes character arrays and string literals). The programmer must arrange for sufficient space for the results of run-time operations such as string concatenation, typically by declaring arrays, or by calling malloc.
strcat() performs no allocation; the second string is appended to the first one, in place. The first (destination) string must be writable and have enough room for the concatenated result. Therefore, one fix would be to declare the first string as an array:
The original call to strcat in the question actually has two problems: the string literal pointed to by s1, besides not being big enough for any concatenated text, is not necessarily writable at all.
其他人关注的是 s1
中的 space 不足以进行字符串连接。但是,这里更大的问题是您正在尝试修改 字符串文字 ,这是未定义的行为。将 s1
定义为具有足够 space 的字符数组应该可行:
char s1[20] = "segmentation";
char *s2 = "fault";
strcat(s1,s2);
printf("concatanated string is %s",s1);
char *s1="segmentation";
s1
是一个不可变的字符串,它将驻留在read-only
内存中。如果您查看 strcat
定义:
char *strcat(char *dest, const char *src)
here
dest
-- 这是指向目标数组的指针,它应该包含一个 C 字符串,并且应该足够大以包含连接的结果字符串。
所以当您调用 char *s3=strcat(s1,s2);
时,您试图修改导致分段错误的不可变字符串。