c - 我是 C 的新手,有人可以解释为什么这个字符串的大小可以改变吗?

标签 c string char printf

我从来没有真正用过很多 C,但我开始尝试使用它。我正在写像下面这样的小片段,试图理解 C 中关键结构/函数的用法和行为。我写的下面的片段试图理解 char* string 之间的区别char string[] 以及字符串的长度是如何工作的。此外,我想看看 sprintf 是否可以用于连接两个字符串并将其设置为第三个字符串。

我发现,我用来存储其他两个串接的第三个字符串必须用 char string[] 语法设置,否则二进制文件会因 SIGSEGV (地址边界错误)。使用数组语法设置它需要一个大小,所以我首先将它设置为其他两个字符串的组合大小。这似乎让我能够很好地执行连接。

不过,出于好奇,我尝试将“串联”字符串扩展为比我分配的长度更长。令我惊讶的是,它仍然有效,并且字符串大小增加了,并且 printf 可能没问题。

我的问题是:为什么会这样,是无效还是有风险/弊端?此外,为什么 char str3[length3] 有效但 char str3[7]sprintf 行尝试执行时导致“SIGABRT(中止)” ?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main() {
    char* str1 = "Sup";
    char* str2 = "Dood";

    int length1 = strlen(str1);
    int length2 = strlen(str2);
    int length3 = length1 + length2;

    char str3[length3];
    //char str3[7];

    printf("%s (length %d)\n", str1, length1);           // Sup (length 3)
    printf("%s (length %d)\n", str2, length2);           // Dood (length 4)
    printf("total length: %d\n", length3);               // total length: 7
    printf("str3 length: %d\n", (int)strlen(str3));      // str3 length: 6
    sprintf(str3, "%s<-------------------->%s", str1, str2); 
    printf("%s\n", str3);                                // Sup<-------------------->Dood

    printf("str3 length after sprintf: %d\n",            // str3 length after sprintf: 29
            (int)strlen(str3));
}

最佳答案

这一行是错误的:

char str3[length3];

您没有考虑终止零。应该是:

char str3[length3+1];

您还试图获取 str3 的长度,但尚未设置。

此外,这一行:

sprintf(str3, "%s<-------------------->%s", str1, str2);

将溢出您为 str3 分配的缓冲区。确保分配足够的空间来容纳完整的字符串,包括终止零。

关于c - 我是 C 的新手,有人可以解释为什么这个字符串的大小可以改变吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1388780/

相关文章:

c - 在给定像素数组的情况下,在 C 中实现涟漪效应

c - For 循环和 While 循环在 C 中选择值

c - 用getche输入字符并存入数组

java.lang.StringIndexOutOfBoundsException : Exception 异常

c++ - C++中如何改变数组的顺序

c++ - wchar_t 和 char16_t 在 Windows 上是一样的吗?

c - 从 C 中的 printf 语句中调用宏函数

c++ - 段错误 - 大小 8 的读取无效

python - Pandas 从一列字符串中删除字符

c++ - 安全地将字节写入流