0
点赞
收藏
分享

微信扫一扫

[Rust] 使用vscode实现HelloWorld程序并进行debug

四月天2021 03-23 06:30 阅读 2
c语言c++

C/C++内存越界的常有例子

1、什么是数组越界?

內存访问越界,就是向系统申请了一块内存,在使用这块内存的时候,超出了你申请的范围。

2、C/C++内存越界的常有例子
2.1、数组下标越界
//内存分配成功,且已经初始化,但是操作越过了内存的边界。这种错误经常是由于操作数组或指针时出现“多 1”或“少 1”
int a[10] = {0};
for (i=0; i<=10; i++)
{
  a[i] = i;
}
2.2、忽略字符串常量后面的长度“\0”,导致申请的空间不够,导致越界操作
char *p1 = “abcdefg”;
char *p2 = (char *)malloc(sizeof(char)*strlen(p1));
strcpy(p2,p1);
//p1 是字符串常量,其长度为 7 个字符,但其所占内存大小为 8 个 byte。初学者往往忘了字符串常量的结束标志 “\0”。这样的话将导致 p1 字符串中最后一个空字符 “\0” 没有被拷贝到 p2 中。
2.3、字符串缓冲区溢出
#include <stdio.h>  
#include <string.h>  
  
int main() {  
    char buffer[10];  
    strcpy(buffer, "Hello, world!"); // 尝试将13个字符的字符串复制到只有10个字符空间的缓冲区中  
    printf("%s\n", buffer);  
    return 0;  
}
//在这个例子中,strcpy函数尝试将一个长度为13个字符(包括结尾的空字符)的字符串复制到只有10个字符空间的buffer中。这会导致缓冲区溢出,可能会覆盖相邻的内存区域,引起程序崩溃或更严重的安全问题。
2.4、使用std::vector越界
#include <iostream>  
#include <vector>  
  
int main() {  
    std::vector<int> vec{1, 2, 3, 4, 5};  
    std::cout << vec.at(10) << std::endl; // 使用at()访问越界元素会抛出std::out_of_range异常  
    return 0;  
}
2.5、指针运算导致的越界
#include <stdio.h>  
  
int main() {  
    int array[5] = {1, 2, 3, 4, 5};  
    int *ptr = array;  
    printf("%d\n", *(ptr + 5)); // 尝试访问ptr指向地址后的第五个整数,越界了  
    return 0;  
}
//在这个例子中,ptr指向array的第一个元素。通过ptr + 5,我们尝试访问array之后的内存位置,这是未定义的,因为array只有5个元素。
2.6、当使用STL容器(如std::vector、std::list等)时,如果迭代器超出了容器的范围,也会发生内存越界。
#include <vector>  
#include <iostream>  
  
int main() {  
    std::vector<int> vec{1, 2, 3, 4, 5};  
    for (std::vector<int>::iterator it = vec.begin(); it != vec.end() + 1; ++it) { 
    // 错误:end()返回的是尾后迭代器,不能加1  
        std::cout << *it << std::endl;  
    }  
    return 0;  
}

3、防止内存越界的策略

总是确保数组和动态分配的内存的索引在有效范围内。
对于循环和迭代器,确保它们不会超出容器的范围。
使用C++的STL容器和算法,它们通常比原生数组更安全,并提供了范围检查的功能。
对于字符串操作,使用C++的std::string类而不是字符数组,它可以自动管理内存并防止缓冲区溢出。
使用内存检测工具,如Valgrind,来检测内存越界问题。
举报

相关推荐

0 条评论