标签: pointers

我需要了解C++中的内存?

我一直在尽力学习C++,但我之前的培训在一个主要问题上不足:内存管理.我的主要语言都有自动垃圾收集,所以跟踪一切从来没有真正必要.我已经尝试过在线阅读C++中的内存管理,但我对此感到怀疑,因为我遗漏了一些东西.

所以,这是一个多部分的问题:

  • 关于内存管理我需要了解的最低限度是什么?(或者,我在哪里找到它)?
  • 我在哪里可以获得中级和高级知识/教程/等(一旦完成基础知识)?

  • 进一步来说:
  • 指针和引用之间的性能差异是什么?
  • 我听说在循环中,你需要确保delete在循环重新迭代之前调用任何新指针.它是否正确?你需要用引用做些什么吗?
  • 什么是内存泄漏的经典例子?
  • 我需要了解以下内容(我是否真的需要使用它们 - 如果是这样,在哪里?):
    • malloc
    • free
    • calloc
    • realloc

***********************更新*******************

这是为了解释在评论一中对lmgtfy的引用(由Ewan提供).如果您开始阅读那里可用的信息,则对初学者没用.我认为这是一个伟大的理论,但它对这个问题既不相关也不有用.

c++ pointers memory-management reference

16
推荐指数
5
解决办法
1513
查看次数

如何将int*转换为int

给定指针int,我如何获得实际int

我不知道这是否可能,但有人可以告诉我吗?

c++ pointers

16
推荐指数
3
解决办法
4万
查看次数

Python和Ctypes:将结构作为指针传递给函数以获取数据

我已经看过其他答案,但似乎无法让这个工作.我正在尝试调用DLL中的函数来与SMBus设备进行通信.该函数接受一个结构的指针,该结构有一个数组作为其中一个字段.所以...

在C:

typedef struct _SMB_REQUEST
{
    unsigned char Address;
    unsigned char Command;
    unsigned char BlockLength;
    unsigned char Data[SMB_MAX_DATA_SIZE];
} SMB_REQUEST;
Run Code Online (Sandbox Code Playgroud)

我想我必须在DLL填充数据数组时设置Address,Command和BlockLength的值.需要此结构的函数将其作为指针

SMBUS_API int SmBusReadByte( SMBUS_HANDLE handle, SMB_REQUEST *request );
Run Code Online (Sandbox Code Playgroud)

所以我在Python中设置了这样的结构:

class SMB_REQUEST(ctypes.Structure):
    _fields_ = [("Address", c_char),
            ("Command", c_char),
            ("BlockLength", c_char),
            ("Data", type(create_string_buffer(SMB_MAX_DATA_SIZE))]
Run Code Online (Sandbox Code Playgroud)

*注意:我也尝试过数据类型的ctypes.c_char*SMB_MAX_DATA_SIZE*

要将指向此类型结构的指针传递给函数,我首先尝试将其初始化,如下所示:

data = create_string_buffer(SMB_MAX_DATA_SIZE)
smb_request = SMB_REQUEST('\x53', \x00', 1, data)
Run Code Online (Sandbox Code Playgroud)

这回应:

TypeError: expected string or Unicode object, c_char_Array_32 found
Run Code Online (Sandbox Code Playgroud)

如果我尝试省略数据数组,如下所示:

smb_request = SMB_REQUEST('\x53', \x00', 1)
Run Code Online (Sandbox Code Playgroud)

不,错误.但是,当我尝试将此传递给函数时:

int_response =  smbus_read_byte(smbus_handle, smb_request))
Run Code Online (Sandbox Code Playgroud)

我明白了:

ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected …
Run Code Online (Sandbox Code Playgroud)

python struct ctypes pointers

16
推荐指数
2
解决办法
3万
查看次数

变量如何在自己的声明中获取自身的地址?

考虑一下:

void* x = &x;

printf("%p\n", x);
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,它编译并运行输出:

7ffb2f7248

在尚未创建的情况下如何x获取自身的地址x

编辑:请注意,在这种情况下,关于它的分配没有歧义,明确提出质疑的内容。

c c++ memory pointers language-lawyer

16
推荐指数
3
解决办法
1588
查看次数

何时取消引用或不取消引用

我正在浏览“Rust Book”网站,以便学习即将到来的工作面试的语言。在向量章节中,有两个代码示例:

fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", i);
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

fn main() {
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想知道,为什么对于第一个样本,当我们将对向量元素i的引用传递到:

println!("{}", i);

但是在我们向向量的每个元素添加 50 的示例中,在添加到 50 之前,我们必须使用 * 取消引用该元素?

我们为什么不/不能做以下事情:

fn main() {
    let v = vec![100, 32, 57];
    for i in &v {
        println!("{}", *i); // why don't we have to dereference before we …
Run Code Online (Sandbox Code Playgroud)

pointers reference dereference rust

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

使用指针的整数值检查指针对齐是否真的定义良好?

是否有一种有保证的(不是实现定义的!)方法来检查指针对齐?

查询指针对齐的最常见方法似乎是:

  1. 转换为整数
  2. 检查整数是否是对齐的倍数:
bool is_aligned(void const *ptr, size_t alignment) {
  return reinterpret_cast<intptr_t>(ptr) % alignment == 0;
}
Run Code Online (Sandbox Code Playgroud)

例如,这就是Boost.Align 检查对齐方式的方式。

然而,至少在 C++17 中,basic.compound#3.4说:

指针类型的值表示是实现定义的。

此外,expr.reinterpret.cast#4说:

指针可以显式转换为任何足够大以容纳它的整型。映射函数是实现定义的。

(例如)将指针表示为具有相反位顺序的整数似乎是合法的,在这种情况下,上面的简单算术将不起作用。

AFAICT,我们可以检查对齐的唯一有保证的方法是使用std::align,如果自由地阅读(我确信这是对 的滥用std::align),可以像这样使用:

bool is_aligned(void const *ptr, size_t alignment) {
  void *mut_ptr = const_cast<void *>(ptr);
  size_t space = alignment;
  return std::align(alignment, alignment, mut_ptr, space) == ptr;
}
Run Code Online (Sandbox Code Playgroud)

然而,在绝大多数平台上,指针只是奇特的整数,或者我希望 Boost 有一个代码路径。是否有任何平台(除了 ds9k :P)其中指针不仅仅是花哨的整数?

通过标准化“应具有与”或“如果与”对齐reinterpret_cast<intptr_t>(ptr)相同的对象表示,我们会​​损失什么?似乎这些都不会排除分段内存或具有陷阱表示的指针,这是我能想到的两种非典型情况。ptrreinterpret_cast<intptr_t>(ptr) % alignment == 0ptr …

c++ pointers undefined-behavior language-lawyer c++17

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

多重继承指针比较

我有一个Derived直接从两个基类继承的类,Base1Base2.我想知道一般来说,将指针与基类进行比较以确定它们是否是同一个Derived对象是否安全:

Base1* p1;
Base2* p2;

/*
 * Stuff happens here. p1 and p2 now point to valid objects of either their
 * base type or Derived
 */

//assert(p1 == p2); //This is illegal
assert(p1 == static_cast<Base1*>(p2)); //Is this ok?
assert(static_cast<Derived*>(p1) == static_cast<Derived*>(p2)); //How about this?
Run Code Online (Sandbox Code Playgroud)

指针保证有效,但不一定指向Derived对象.我的猜测是这可能很好,但我想从技术C++的角度来看它是否可以.我实际上从不对指针进行任何操作,我只是想知道它们是否指向同一个对象.

编辑:如果我可以保证p1p2指向Derrived对象似乎是安全的.我基本上想知道如果它们不是 - 如果一个或两个都指向基础对象,它是否安全,那么比较是否必然会失败?同样,我可以保证指针有效(即,p1永远不会指向Base2对象,反之亦然)

c++ inheritance pointers multiple-inheritance

15
推荐指数
2
解决办法
5076
查看次数

通过指针向量迭代

我正试图通过玩家手牌迭代.

Player.cpp

vector<Card*>::iterator iter;
    for(iter = current_cards.begin(); iter != current_cards.end(); iter++) {
        cout << iter->display_card() << endl;
    }
Run Code Online (Sandbox Code Playgroud)

它在

cout << iter->display_card() << endl;
Run Code Online (Sandbox Code Playgroud)

目前提出"错误:表达式必须具有指针类型".

同样,current_cards声明为:

vector<Card*>current_cards;
Run Code Online (Sandbox Code Playgroud)

此外,display_card()方法很简单:

Card.cpp

string Card::display_card(){
    stringstream s_card_details;
    s_card_details << "Colour: " << card_colour << "\n";
    s_card_details << "Type: " << card_type << "\n";

    return s_card_details.str();
}
Run Code Online (Sandbox Code Playgroud)

我已经查看了各种资源,并且针对类似问题提出的所有建议都没有对我有用.谢谢你的帮助!

c++ pointers vector object

15
推荐指数
2
解决办法
3万
查看次数

两次指针自由调用

我在讲座中被教过,free()两次拨打指针真是非常糟糕.我知道NULL在释放它之后立即设置指针是一种很好的做法.

但是,我仍然没有听到任何解释为什么会这样.根据我的理解,方式malloc()有效,它应该在技术上跟踪它已经分配的指针并让你使用.那么为什么它不知道它接收到的指针是否free()已被释放?

当你打电话free()给以前已经被释放的位置时,我很乐意理解,内部会发生什么.

c malloc free pointers dynamic-memory-allocation

15
推荐指数
2
解决办法
6568
查看次数

x86程序集指针

希望这不是一个愚蠢的问题,但我试图围绕汇编指针.

究竟有什么区别:

mov eax, ebx
Run Code Online (Sandbox Code Playgroud)

mov [eax], ebx
Run Code Online (Sandbox Code Playgroud)

何时应该dword ptr [eax]使用?

另外,当我尝试这样做时,mov eax, [ebx]我得到一个编译错误,为什么会这样?

x86 assembly pointers

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