您的程序 在运行时进行缓冲区溢出strcat(arr3, arr4)
,因为arr3
大小正好等于"Mr."
string 的长度,所以它没有额外的内存空间用于额外的字符(来自arr4
)。
的大小arr3
应该是 a 的至少字符串长度"Mr. " + "Smith" + 1
(字符串终止字符的额外 1\0
)
我的建议是使用动态内存分配来获得足够大小的缓冲区,请执行以下代码:
char arr3[] = "Mr. ";
char arr4[] = "Smith";
length = strlen(arr3) + strlen(arr4) + 1; //cal-length (sufficient long buffer)
char* new_arr = malloc(length); // allocate memory
strcpy(new_arr, arr3); // copy first string
strcat(new_arr, arr4); // then check your function to concat strings
核心转储的原因:
在您的代码中:
char arr3[] = "Mr. ";
is的大小arr2
= 字符串"Mr."
长度 + 1
(1 因为\0
) 字符的长度。第一个在第一个 while 循环中将指针strcat()
移动temp
到指向 null 的位置while(*tmp) ++tmp ;
。
之后,在第二个 while 循环中,while( (*tmp++ = *src++ ) != '\0') ;
您尝试访问和分配未分配的内存(我将超出您的进程控制)并访问未分配的内存是 C 中未定义的行为。
编辑:
代码 arr3
如下图所示,其中temp
指向arr3
数组:
arr3
temp 5 6 7 8
+-----+ +--+--+--+---+
| 5 +----->|M |r |. |\0 |
+-----+ +--+--+--+---+
当循环while(*tmp) ++tmp ;
中断temp
开始指向存储8
null\0
的内存位置时,如下图所示。
arr3
temp 5 6 7 8
+-----+ +--+--+--+---+
| 8 | |M |r |. |\0 |
+-----+ +--+--+--+---+
| ^
+--------------------|
当您temp++
在循环 中执行时while( (*tmp++ = *src++ ) != '\0') ;
,temp
递增以指向内存位置9
及以后,但访问和分配内存9
,10
.. 是非法的,因为它没有分配。这会导致操作系统内核向导致异常的进程发送信号核心转储。(值得注意的是:当操作系统检测到进程违反内存权限时——对有效内存的无效访问会给出:SIGSEGV 并且对无效地址的访问会给出:SIGBUS)。
程序错误信号:
当这些程序错误信号之一终止进程时,它还会写入一个核心转储文件,该文件记录终止时进程的状态。核心转储文件被命名为“核心”,并写入当时进程中的当前目录中。(在 GNU 系统上,您可以使用环境变量 COREFILE 指定核心转储的文件名。)核心转储文件的目的是让您可以使用调试器检查它们以调查导致错误的原因。
如果您分配额外的内存(如@JerryCoffin 和@Paul R 建议的那样),那么您可以访问超出\0
(内存位置8
)的内存没问题。
注意:如果你在声明时没有给出大小,那么数组的大小将等于字符串的大小,例如char arr3[] = "Mr. ";
大小为5
. 但是,如果您明确给出大小,char arr3[84] = "Mr. ";
则将大小aar3
和84
初始内存包含Mr.
在0
所有位置的其余部分中。
在我的解决方案中,我完全分配了与字符串一样大的新内存块,arr3
并且arr4
可以使用动态内存分配(malloc()
函数)与空符号一起存储。此外,如果您使用ptr = malloc()
或分配动态内存,ptr = calloc()
那么您应该在使用free(ptr)
.