update:纠正malloc(sizeof(500))后仍然存在分割错误
在下面的代码中,我遇到了一个分段错误:
#include <iostream>
#include <vector>
#include <functional>
struct Data {
std::string name;
std::function<int()> work;
std::vector<int*> v1 {nullptr, nullptr, nullptr, nullptr};
std::vector<int*> v2 {nullptr, nullptr, nullptr, nullptr};
int* v3 {nullptr};
int* v4 {nullptr};
};
int main() {
std::cout << sizeof(Data) << "\n"; // Just to make sure sizeof(Data) < 500
auto raw = malloc(500); // Allocate memory
auto int_ptr = static_cast<int*>(raw);
int_ptr ++;
auto ptr = reinterpret_cast<Data*>(int_ptr);
new (ptr) Data(); // GDB reports segmentation fault here
free(raw);
}编译命令:
clang++-9 -std=c++14 -stdlib=libc++ -ggdb3 prog.cpp -lc++abi -O2我认为内存应该足够大来存储Data,但是为什么在new中会出现分段错误?
发布于 2020-03-05 05:55:45
你的问题是:
auto raw = malloc(sizeof(500)); '500‘是一个整数,所以sizeof(500)返回4。
auto raw = malloc(500); 与此无关,但您可能需要:
auto int_ptr = static_cast<int*>(raw);
int_ptr += 2; 这样指针就可以保持8字节对齐(假设您使用的是64位OS)。另外,不要忘记在调用空闲之前调用dtor (否则内存泄漏)。
ptr->~Data();发布于 2020-03-05 07:45:42
通常,由于不正确的对齐,代码具有未定义的行为。我将尝试在下面的例子中解释它。
让我们假设您所处的是一个具有4字节int的64位架构。在这样的系统上,malloc通常会给你一个16字节对齐的内存块.然后,当将4个字节添加到这个边界(raw加上4个字节)时,得到的地址(ptr)是对齐的4字节,而不是对齐的8字节或16字节。
现在,Data有一些自然的对齐方式,很可能是8字节。您可以通过alignof(Data)表达式找到它。当您尝试在4字节对齐地址上创建Data类型的对象时,此导致未定义的行为。
另外,正如其他人所指出的,您需要手动调用通过放置new创建的对象的析构函数。
发布于 2020-03-05 07:06:06
如果您正在编写C++,通常使用malloc并不好。您可以使用向量作为缓冲区,也可以创建字符数组。
int main() {
std::vector<char> buffer(500);
auto ptr = reinterpret_cast<Data*>(buffer.data());
new (ptr) Data;
}https://stackoverflow.com/questions/60538767
复制相似问题