范围:我一直在试图了解在C中使用strncpy函数时缓冲区溢出是如何发生的,我发现了这种非常不寻常的行为.

我有两个字符数组,分别是arr1arr2.我正在try 将20字节的数据从大小为16的arr1数组移动到大小为5的arr2array.根据我的理解,这应该会触发缓冲区溢出,但我发现arr2中存储的字符串的长度会增加以容纳字符串,但数组的大小保持不变.

#include<stdio.h>
#include<string.h>
int main(){
    char arr1[]="Buffer overflow";
    char arr2[5];
    printf("Size of array1 %d\n",sizeof(arr1));
    strncpy(arr2,arr1,20);
    printf("\nAfter copy\n");
    printf("Length of arr2: %d\n",strlen(arr2));
    printf("Size of arr2: %d\n",sizeof(arr2));
    printf("Arr2: %s\n",arr2);
    return 0;
}



我发现以下输出非常令人惊讶,

Size of array1 16

After copy
Length of arr2: 15
Size of arr2: 5
Arr2: Buffer overflow

Problem:当arr2的大小只有5时,arr2的长度怎么可能是15?一个大小为5的字符数组如何容纳另一个大小为20的字符数组?

推荐答案

程序具有未定义的行为,因为此调用

strncpy(arr2,arr1,20);

覆盖字符数组arr2外部的内存.函数对数组arr2的大小一无所知.(请记住,用作函数参数的数组arr2会隐式转换为指向其第一个元素的指针.)它信任函数的调用方正确指定了复制的字符数.函数调用方有责任保证函数的正确工作.

数组的大小没有更改,此输出确认

Size of arr2: 5

此呼叫

printf("Length of arr2: %d\n",strlen(arr2));

不输出数组arr2的大小.它输出复制的字符串"Buffer overflow"的长度.

请注意,必须将转换说明符%zu用于size_t类型的对象,而不是转换说明符%d.

C++相关问答推荐

当包含头文件时,gcc会发出隐式函数声明警告

Zig将std.os.argv转换为C类型argv

从C函数调用asm函数时生成错误的BLX指令(STM32H753上的gcc)

为什么getchar()挂起了,尽管poll()返回了一个好的值?""

在函数中使用复合文字来初始化C语言中的变量

堆栈帧和值指针

测量ARM MCU中断延迟的问题

在一个小型玩具项目中实现终端历史记录功能

Rust FFI--如何用给出返回引用的迭代器包装C风格的迭代器?

试图从CSV文件中获取双精度值,但在C++中始终为空

Sizeof(&Q;字符串&Q;)的正确输出是什么?

&;(str[i])和(&;str)[i]有什么区别?

S将C语言宏定义为自身的目的是什么?(在glibc标题中看到)

当内存来自Malloc时,将char*转换为另一个指针类型是否违反了严格的别名规则?

C语言中的外部关键字

如何将大写/小写土耳其字母相互转换?

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

C中的char**v*char[]

I';我试着从.txt文件中读取文本,并用c计算其中的单词数量

中位数和众数不正确