gpt4 book ai didi

c++ - C++ 类的 C 包装器返回不正确的地址

转载 作者:搜寻专家 更新时间:2023-10-31 00:09:24 26 4
gpt4 key购买 nike

我的 C++ 头文件是

header.hh

#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
#include <string>
class A
{
uint32_t a;
public:
A(){
a = 0;
}
void update(uint32_t b) {
a = b;
}
};
#else
typedef struct A A;
#endif //__cplusplus
#ifdef __cplusplus
extern "C" {
void* newA(void);
void deleteA(A* a);
void update(A*a,uint32_t b);
}
#endif

我的c++文件是

class.cc

#include "header.hh"
#include <iostream>
extern "C" {
void* newA(void) {
A* a = new A();
return (reinterpret_cast <void*> (a));
}
void deleteA(A* a) {
delete a;
}
void update(A* a,uint32_t b){
a->update(b);
}
}

ma​​in.c

#include "header.hh"
#include <stdio.h>
int main()
{
A* a = (A*) newA();
deleteA(a);
}

生成文件

CFLAGS=-Wall -g -ansi -pedantic -std=c99
CCFLAGS=-Wall -g
LDFLAGS=-g -Wall -lstdc++

OBJS=class.o main.o
PROG=test

all:$(PROG)
default: all

%.o: %.cc
$(CC) $(CCFLAGS) -c $<

%.o: %.c
$(CC) $(CFLAGS) -c $<

$(PROG): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $@

clean:
rm -rf $(OBJS)
rm -rf $(PROF)

当我编译并运行这个程序时,我在尝试调用 Main 中的析构函数时看到一个段错误。

我进入gdb,发现“a”在class.cc中的地址是0x7fff980097a0,在main中是0xffffffff980097a0

是什么导致地址被更改?

我在 ubuntu 14.04 上使用 4.8.4 版本的 gcc。

最佳答案

当您使用 C 编译器编译 main.c 时,它不会包含 newAdeleteAupdate 函数(它们被 #ifdef __cplusplus 包围)。

因此,它将采用默认签名 int newA()(与其他两个类似)。

这意味着在这一行中:

A* a = (A*) newA();

newA() 返回的值被视为 int,然后转换为 A*。将 int 转换为指针类型的结果是实现定义的。在您的平台上,该行为似乎与您观察到的一样。

很可能,在您的平台上,sizeof(int)4,而 sizeof(void*)8。在这种情况下,0x7fff980097a0 在被视为 int 时被截断为 0x980097a0,然后在转换时扩展为 0xfffffff980097a0A*。这正是您所观察到的。

相反,试试这个让声明对 C 编译器可见:

#ifdef __cplusplus
extern "C" {
#endif
void* newA(void);
void deleteA(A* a);
void update(A*a,uint32_t b);
#ifdef __cplusplus
}
#endif

关于c++ - C++ 类的 C 包装器返回不正确的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43490530/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com