相关疑难解决方法(0)

何时访问指向"死"对象的指针有效?

首先,澄清一点,我不是在谈论解除引用无效指针!

考虑以下两个例子.

例1

typedef struct { int *p; } T;

T a = { malloc(sizeof(int) };
free(a.p);  // a.p is now indeterminate?
T b = a;    // Access through a non-character type?
Run Code Online (Sandbox Code Playgroud)

例2

void foo(int *p) {}

int *p = malloc(sizeof(int));
free(p);   // p is now indeterminate?
foo(p);    // Access through a non-character type?
Run Code Online (Sandbox Code Playgroud)

以上示例中的任何一个都会调用未定义的行为吗?

上下文

提出这个问题是为了回应这一讨论.建议是,例如,指针参数可以通过x86段寄存器传递给函数,这可能导致硬件异常.

根据C99标准,我们学习以下内容(强调我的):

[3.17] 不确定值 - 未指定的值或陷阱表示

然后:

[6.2.4 p2]当指向的对象到达其生命周期的末尾时,指针的值变得不确定.

然后:

[6.2.6.1 p5]某些对象表示不需要表示对象类型的值.如果对象的存储值具有这样的表示并且由不具有字符类型的左值表达式读取,则行为是未定义的.如果这样的表示是由副作用产生的,该副作用通过不具有字符类型的左值表达式修改对象的全部或任何部分,则行为是未定义的.这种表示称为 …

c pointers undefined-behavior language-lawyer

53
推荐指数
2
解决办法
2546
查看次数

两个临时表的地址是否保证在同一个表达式中不同?

考虑以下程序:

#include <iostream>

int const * f(int const &i) 
{ 
  return &i; 
}

int main() 
{
  std::cout << f(42);  // #1
  std::cout << f(42);  // #2

  std::cout << f(42) << f(42);  // #3
}
Run Code Online (Sandbox Code Playgroud)

根据编译器和设置的优化级别,打印在行上的地址可能彼此不同#1#2也可能不同。

但是,无论选择何种编译器或优化级别,行#3中打印的 2 个地址总是彼此不同。

这是一个可以玩的演示

那么f在每种情况下返回什么的规则是什么?

c++ pointers language-lawyer temporary-objects

30
推荐指数
2
解决办法
1776
查看次数

将地址插入集合中,集合的大小小于预期

我的大小是1.不应该是4吗?我将整数的地址插入集合中.

void func(set<int*>& s1, set<int*>& s2, int a)
{
    s1.insert(&a);
    s2.insert(&a);
}

int main()
{
    set<int*> s1, s2;

    int a = 1, b = 2, c = 3, d = 4;
    func(s1, s2, a);
    func(s1, s2, b);
    func(s1, s2, c);
    func(s1, s2, d);

    cout<<"  s1.size = "<<s1.size()<<"  s2.size = "<<s2.size()<<endl;
}
Run Code Online (Sandbox Code Playgroud)

c++ set

29
推荐指数
2
解决办法
2380
查看次数

在遍历动态矢量时使用auto的不寻常行为

我正在遍历带有auto(附加代码)的向量.在遍历时,我还在后面添加了一些元素.我没想到我得到的输出.

#include <iostream>
#include <vector>
using namespace std;

vector <int> dynamic_vector;

void access( )
{
    for ( auto i : dynamic_vector ) {
        if ( i == 3 ) {
            dynamic_vector.push_back( 4 );
            dynamic_vector.push_back( 5 );
        }
        cout << i << endl;
    }
}

int main() {
    dynamic_vector.push_back( 1 );
    dynamic_vector.push_back( 2 );
    dynamic_vector.push_back( 3 );
    access( );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
Run Code Online (Sandbox Code Playgroud)

我期待从1到5的所有数字都会被打印出来.我无法理解如何遍历汽车工作?

c++ iterator vector auto c++11

6
推荐指数
2
解决办法
87
查看次数

比较std :: vector的指针以检查相等性是否安全?

在同一时间,我创建了一个指针指向std::vector,然后我做了一些push_back,reserve,resize操作与向量,这样的操作之后,是安全的指针比较的是向量的地址,以检查是否指针指向该向量,因为可能会有一些内存重新分配.

例如

std::vector<int> vec;
vector<int>* pVec = &vec;
vec.reserve(10000);
assert(pVec == &vec);
vec = anotherVec;
assert(pVec == &vec);
Run Code Online (Sandbox Code Playgroud)

更重要的是,将指针与向量的第一个值进行比较是否安全?例如:

std::vector<int> vec(1,0);
int* p = &vec[0];
// some operation here
assert(p == &vec[0]);
Run Code Online (Sandbox Code Playgroud)

正如我自己测试的那样,第一种情况似乎是安全的,而第二种情况则不然,但我不能确定.

c++ pointers vector c++11

5
推荐指数
1
解决办法
576
查看次数

基于已删除的内存UB的指针算术和比较?

Fox例子:

int* a = new int[10];
int* b = a;
int* e = a + 10;
delete[] a;
for (; b != e; ++b);
Run Code Online (Sandbox Code Playgroud)

我知道解除引用无效指针将是UB.但是如何比较和增加呢?

背景

这是一个问题,OP在基于范围的for循环中添加元素,这可能导致迭代器变为无效.但是他最后在向量中添加了元素,之后迭代器将被增加并进行比较,而不是解除引用.是UB吗?

c++ pointers iterator

5
推荐指数
0
解决办法
72
查看次数

是否可以使用指向"if"语句中声明的变量的地址的指针

是否可以使用指向"if"语句中声明的变量的地址的指针?示例如下:

...
int *pTest = 0;
if (...)
{
  int x = 10;
  pTest = &x;
}
else
{
  int x = 100;
  pTest = &x;
}
...
// use pTest 
Run Code Online (Sandbox Code Playgroud)

c++ variables pointers if-statement memory-address

2
推荐指数
1
解决办法
91
查看次数

多个指针指向相同的数据

int a = 10; 
int* ptrA = &a;
int* ptrB = &a;

delete ptrA;

return 0;
Run Code Online (Sandbox Code Playgroud)

这不应该导致泄漏,导致mem/data被释放ptrA,但是我们有2个指向有效地址的指针,其数据刚被删除?它是如何工作的?

c++ memory

1
推荐指数
1
解决办法
98
查看次数