C/C++中未定义行为
生活随笔
收集整理的这篇文章主要介绍了
C/C++中未定义行为
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
C/C++中未定义行为
1、变量类型没有指定。
2、指定类型的方式与C++混淆了,特别是在.c文件中容易出现这种错误。
3、变量指定了类型,但是与使用的变量名不符合,使用的变量名会提示为未定义。
在C++中常见的未定义行为
C++ 标准中有大量的未定义行为,如果在标准中查找 undefined behavior,将会看到几十条相关内容。如此众多的未定义行为,无疑给我们带来了许多麻烦,下面我们将列出一些常见的未定义行为,写程序时应该尽量避免。
指针相关的常见未定义行为有如下内容:
解引用 nullptr 指针;
解引用一个未初始化的指针;
解引用 new 操作失败返回的指针;
指针访问越界(解引用一个超出数组边界的指针);
解引用一个指向已销毁对象的指针;
解引用一个指向已销毁对象的指针,有时候很容易就会犯这个错误,例如在函数中返回局部指针地址。 一些简单的错误代码如下:
#include <iostream>
int * get(int tmp){
return &tmp;
}
int main()
{
int *foo = get(10);
std::cout << *foo << std::endl; // Undefined Behavior;
int arr[] = {1,2,3,4};
std::cout << *(arr+4) << std::endl; // Undefined Behavior;
int *bar=0;
*bar = 2; // Undefined Behavior;
std::cout << *bar << std::endl;
return 0;
}
#include <iostream>
int * get(int tmp){
return &tmp;
}
int main()
{
int *foo = get(10);
std::cout << *foo << std::endl; // Undefined Behavior;
int arr[] = {1,2,3,4};
std::cout << *(arr+4) << std::endl; // Undefined Behavior;
int *bar=0;
*bar = 2; // Undefined Behavior;
std::cout << *bar << std::endl;
return 0;
}
其他常见未定义行为如下:
有符号整数溢出(文章开头的例子);
整数做左移操作时,移动的位数为负数;
整数做移位操作时,移动的位数超出整型占的位数。(int64_t i = 1; i <<= 72);
尝试修改字符串字面值或者常量的内容;
对自动初始化且没有赋初值的变量进行操作;(int i; i++; cout << i;)
在有返回值的函数结束时不返回内容;
- A:int i=0;i=(i++);
- B:char *p=”hello”;p[1]=’E’
- C:char *p=”hello”;char ch=*p++
- D:int i=0;printf(“%d%d\n”,i++ i--)
- E:都是未定义行为
- F:都不是未定义行为
D:D 答案有点问题,应为, int i=0;printf(“%d%d\n”,i++ , i--)
一句话,未定义行为就是运行结果不确定
1、变量类型没有指定。
2、指定类型的方式与C++混淆了,特别是在.c文件中容易出现这种错误。
3、变量指定了类型,但是与使用的变量名不符合,使用的变量名会提示为未定义。
在C++中常见的未定义行为
C++ 标准中有大量的未定义行为,如果在标准中查找 undefined behavior,将会看到几十条相关内容。如此众多的未定义行为,无疑给我们带来了许多麻烦,下面我们将列出一些常见的未定义行为,写程序时应该尽量避免。
指针相关的常见未定义行为有如下内容:
解引用 nullptr 指针;
解引用一个未初始化的指针;
解引用 new 操作失败返回的指针;
指针访问越界(解引用一个超出数组边界的指针);
解引用一个指向已销毁对象的指针;
解引用一个指向已销毁对象的指针,有时候很容易就会犯这个错误,例如在函数中返回局部指针地址。 一些简单的错误代码如下:
#include <iostream>
int * get(int tmp){
return &tmp;
}
int main()
{
int *foo = get(10);
std::cout << *foo << std::endl; // Undefined Behavior;
int arr[] = {1,2,3,4};
std::cout << *(arr+4) << std::endl; // Undefined Behavior;
int *bar=0;
*bar = 2; // Undefined Behavior;
std::cout << *bar << std::endl;
return 0;
}
#include <iostream>
int * get(int tmp){
return &tmp;
}
int main()
{
int *foo = get(10);
std::cout << *foo << std::endl; // Undefined Behavior;
int arr[] = {1,2,3,4};
std::cout << *(arr+4) << std::endl; // Undefined Behavior;
int *bar=0;
*bar = 2; // Undefined Behavior;
std::cout << *bar << std::endl;
return 0;
}
其他常见未定义行为如下:
有符号整数溢出(文章开头的例子);
整数做左移操作时,移动的位数为负数;
整数做移位操作时,移动的位数超出整型占的位数。(int64_t i = 1; i <<= 72);
尝试修改字符串字面值或者常量的内容;
对自动初始化且没有赋初值的变量进行操作;(int i; i++; cout << i;)
在有返回值的函数结束时不返回内容;
总结
以上是生活随笔为你收集整理的C/C++中未定义行为的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 深入理解C++重载函数
- 下一篇: C++中的覆盖(重写)、重载、隐藏(重定